В очередной раз прошу о помощи, чтобы разобраться с GDIPlus.
Есть созданный в программе битмап вполне определенного вида:
В верхней части этого битмапа находится некое изображение, в нижней - фон. Стоит задача дать юзеру возможность сохранить такое изображение в png с заменой этого нижнего фона на прозрачность. Высота верхней части изображения известна, ее вычислять не надо.
В спойлере упрощенный код скрипта, отвечающий за создание и сохранение в файл этого битмапа. Упрощенный - в том смысле, что создание такого варианта файла и сохранение его в png есть лишь один из вариантов возможных действий, но с вариантами создания файла без прозрачного фона и с сохранением его в другие форматы у меня уже проблем нет. Проблема только с созданием прозрачности. Поэтому я убрал из кода все дополнительные варианты действий, оставил только те части функций, которыми создается такой файл и сохраняется.
Поиском я нашел (в основном, на английском форуме) примеры как заменять пиксели на прозрачный фон), но не смог нормально понять этот код, а попытка скопировать чужой с какой-то минимальной правкой успеха не дала. Эти вставки в функции закомментарены.
Хочется разобраться. Я понял, что надо изменить атрибуты у пикселей изображения на $GDIP_PXF32ARGB, чтобы задействовать альфа-канал. Далее, похоже, создается клон изображения, пиксели, которые будут правиться лочатся, потом в них регулярными выражениями заменяется цвет с включением прозрачности. С каждым шагом понятно все меньше.
Подскажите, пожалуйста. Желательно, с работающим примером.
Спасибо.
Есть созданный в программе битмап вполне определенного вида:
В верхней части этого битмапа находится некое изображение, в нижней - фон. Стоит задача дать юзеру возможность сохранить такое изображение в png с заменой этого нижнего фона на прозрачность. Высота верхней части изображения известна, ее вычислять не надо.
В спойлере упрощенный код скрипта, отвечающий за создание и сохранение в файл этого битмапа. Упрощенный - в том смысле, что создание такого варианта файла и сохранение его в png есть лишь один из вариантов возможных действий, но с вариантами создания файла без прозрачного фона и с сохранением его в другие форматы у меня уже проблем нет. Проблема только с созданием прозрачности. Поэтому я убрал из кода все дополнительные варианты действий, оставил только те части функций, которыми создается такой файл и сохраняется.
Код:
...
$hBMP = _GetImage($CurCover, $PreviewSizeW, $PreviewSizeH, $NewSizeW, $NewSizeH)
_hBmpToFile($CurRename, $hBMP)
...
Func _GetImage($sFile, $pW, $pH, $vW, $vH, $iBkClr = 0xFFFFFF)
Local $hBmp1, $hBitmap, $hGraphic, $hImage, $iW, $iH, $aGS, $hBmp2
_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile($sFile)
$iW = _GDIPlus_ImageGetWidth($hImage)
$iH = _GDIPlus_ImageGetHeight($hImage)
$aGS[3] = $vH
$aGS[2] = Round(($iW/$iH) * $vH)
$aGS[0] = 0
$aGS[1] = 0
If $aGS[2] > $pW Then $aRet[0] = (($pW - $aRet[2]) / 2)
$hBmp1 = _WinAPI_CreateBitmap($pW, $pH, 1, 32)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp1)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_WinAPI_DeleteObject($hBmp1)
_GDIPlus_GraphicsClear($hGraphic, BitOR(0xFF000000, $iBkClr))
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, $aGS[0], $aGS[1], $aGS[2], $aGS[3])
; $hBitmap2 = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, $iW, $iH, $GDIP_PXF32ARGB)
; _GDIPlus_BitmapDispose($hBitmap)
; $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap2, 0, $aGS[3] + 1, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32ARGB)
; $tPixels = DllStructCreate("byte[" & $iH * $iW * 4 & "]", DllStructGetData($tBitmapData, "Scan0")) ; Create DLL structure for all pixels
; DllStructSetData($tPixels, 1, StringReplace(DllStructGetData($tPixels, 1), "000000FF", "00000000"))
; _GDIPlus_BitmapUnlockBits($hBitmap2, $tBitmapData)
; $tPixels = 0
; $tBitmapData = 0
_GDIPlus_ImageDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphic)
; $hBmp2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap2)
; _GDIPlus_BitmapDispose($hBitmap2)
$hBmp2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()
Return $hBmp2
EndFunc
Func _hBmpToFile($fName, ByRef $hBMP)
_GDIPlus_Startup()
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
_GDIPlus_ImageSaveToFile($hImage, $fName)
_WinAPI_DeleteObject($hBMP)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
EndFunc
Поиском я нашел (в основном, на английском форуме) примеры как заменять пиксели на прозрачный фон), но не смог нормально понять этот код, а попытка скопировать чужой с какой-то минимальной правкой успеха не дала. Эти вставки в функции закомментарены.
Хочется разобраться. Я понял, что надо изменить атрибуты у пикселей изображения на $GDIP_PXF32ARGB, чтобы задействовать альфа-канал. Далее, похоже, создается клон изображения, пиксели, которые будут правиться лочатся, потом в них регулярными выражениями заменяется цвет с включением прозрачности. С каждым шагом понятно все меньше.
Подскажите, пожалуйста. Желательно, с работающим примером.
Спасибо.