genius257 Posted December 17, 2012 Share Posted December 17, 2012 (edited) So I wanted to apply custom shapes to images (like get a part of the image shaped as an specified ellipse). I looked, but could'n find any. I ended up making something inspired by Photoshop's ability to Make layer mask's. Here's an Example: expandcollapse popup#include <Array.au3> #include <GDIPlus.au3> _GDIPlus_Startup() $hImage=_GDIPlus_ImageLoadFromFile(@ScriptDir&"\1.png") $hImage2=CreateLayerMask($hImage) $hGraphics=_GDIPlus_ImageGetGraphicsContext($hImage2) $hBrush=_GDIPlus_BrushCreateSolid(0xFFFFFFFF) _GDIPlus_GraphicsFillEllipse($hGraphics, 10, 10, _GDIPlus_ImageGetWidth($hImage2)-20, _GDIPlus_ImageGetHeight($hImage2)-20, $hBrush) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGraphics) $hBitmap=ApplyLayerMask($hImage, $hImage2) _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir&"\2.png") _GDIPlus_ImageDispose($hImage) _GDIPlus_ImageDispose($hImage2) _GDIPlus_ImageDispose($hBitmap) _GDIPlus_Shutdown() Func CreateLayerMask($hImage) $iWidth = _GDIPlus_ImageGetWidth($hImage) $iHeight = _GDIPlus_ImageGetHeight($hImage) $HBITMAP = _WinAPI_CreateBitmap($iWidth, $iHeight, 1, 32) $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($HBITMAP) _WinAPI_DeleteObject($HBITMAP) $hBitmap = _GDIPlus_BitmapCloneArea($hBmp, 0, 0, $iWidth, $iHeight, $GDIP_PXF32ARGB) _GDIPlus_BitmapDispose($hBmp) Return $hBitmap EndFunc Func ApplyLayerMask($hImage1, ByRef $hImage2, $bInvert=False) If $bInvert Then $iRBGA='000000FF' Else $iRBGA='FFFFFFFF' EndIf $iWidth = _GDIPlus_ImageGetWidth($hImage1) $iHeight = _GDIPlus_ImageGetHeight($hImage1) $HBITMAP = _WinAPI_CreateBitmap($iWidth, $iHeight, 1, 32) $hBmp=_GDIPlus_BitmapCreateFromHBITMAP($HBITMAP) _WinAPI_DeleteObject($HBITMAP) $hBitmap = _GDIPlus_BitmapCloneArea($hBmp, 0, 0, $iWidth, $iHeight, $GDIP_PXF32ARGB) _GDIPlus_BitmapDispose($hBmp) $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0) _GDIPlus_GraphicsDispose($hGraphics) $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) $tBitmapData2 = _GDIPlus_BitmapLockBits($hImage2, 0, 0, $iWidth, $iHeight, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) $tPixels = DllStructCreate("byte[" & $iHeight * $iWidth * 4 & "]", DllStructGetData($tBitmapData, "Scan0")) ; Create DLL structure for all pixels $tPixels2 = DllStructCreate("byte[" & $iHeight * $iWidth * 4 & "]", DllStructGetData($tBitmapData2, "Scan0")) ; Create DLL structure for all pixels $sPixels = DllStructGetData($tPixels, 1) $sPixels2 = DllStructGetData($tPixels2, 1) $iPixels=StringLen($sPixels) $sPixels=StringMid($sPixels, 3, $iPixels-2) $sPixels2=StringMid($sPixels2, 3, $iPixels-2) $iPixels=StringLen($sPixels) Dim $aPixels[$iPixels/8] For $i=0 To $iPixels/8-1 If $iRBGA=StringMid($sPixels2, ($i*8)+1, 8) Then $aPixels[$i]=StringMid($sPixels, ($i*8)+1, 8) Else $aPixels[$i]='00000000' EndIf Next $sPixels=_ArrayToString($aPixels, "") $sPixels="0x"&$sPixels $sPixels1="0x"&$sPixels2 DllStructSetData($tPixels, 1, $sPixels) _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData) _GDIPlus_BitmapUnlockBits($hImage2, $tBitmapData2) $tPixels = 0 $tPixels2 = 0 $tBitmapData = 0 $tBitmapData2 = 0 Return $hBitmap EndFunc Example image: http://green-tag.dk/AutoIt/1.png (Use bigger image if you wish) Problem is the speed. The bigger the image, the longer it takes, i just can't think of any way to make this faster. Any suggestions, are appreciated! Thanks in advance Edited September 2, 2016 by genius257 Makes it easy to see problem was solved, from topic list My highlighted topics: AutoIt Package Manager, AutoItObject Pure AutoIt, AutoIt extension for Visual Studio Code Github: AutoIt HTTP Server, AutoIt HTML Parser Link to comment Share on other sites More sharing options...
Solution UEZ Posted December 17, 2012 Solution Share Posted December 17, 2012 (edited) Try this: expandcollapse popup#include <GDIPlus.au3> _GDIPlus_Startup() $hImage=_GDIPlus_ImageLoadFromFile(@ScriptDir & "1.png") $hNewBitmap = _GDIPlus_ImageShapeCircle($hImage, _GDIPlus_ImageGetWidth($hImage) /2) _GDIPlus_ImageSaveToFile($hNewBitmap, @ScriptDir & "2.png") _GDIPlus_ImageDispose($hImage) _GDIPlus_BitmapDispose($hNewBitmap) _GDIPlus_Shutdown() ShellExecute(@ScriptDir & "2.png") Exit Func _GDIPlus_ImageShapeCircle($hBitmap, $iRadius, $iTiling = 4) ;coded by UEZ 2012-12-17 Local $iWidth = $iRadius * 2, $iHeight = $iWidth Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateTexture", "ptr", $hImage, "int", $iTiling, "int*", 0) If @error Then Return SetError(1, 0, 0) Local $hTexture = $aResult[3] $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0) If @error Then Return SetError(2, 0, 0) Local $hImage = $aResult[6] Local $hGfxCtxt = _GDIPlus_ImageGetGraphicsContext($hImage) _GDIPlus_GraphicsSetSmoothingMode($hGfxCtxt, 2) DllCall($ghGDIPDll, "uint", "GdipSetPixelOffsetMode", "handle", $hGfxCtxt, "int", 2) _GDIPlus_GraphicsFillEllipse($hGfxCtxt, 0, 0, $iWidth, $iHeight, $hTexture) _GDIPlus_BrushDispose($hTexture) _GDIPlus_GraphicsDispose($hGfxCtxt) Return $hImage EndFunc Func _GDIPlus_ImageShapeCircle2($hBitmap, $iRadius, $fDX = 0, $fDY = 0, $iTiling = 4) ;coded by UEZ 2012-12-17 Local $iWidth = $iRadius * 2 If _GDIPlus_ImageGetWidth($hBitmap) < $iWidth Then $iWidth = _GDIPlus_ImageGetWidth($hBitmap) Local $iHeight = $iWidth Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateTexture2", "handle", $hBitmap, "int", $iTiling, "float", $fDX, "float", $fDY, "float", $iWidth, "float", $iHeight, "int*", 0) If @error Then Return SetError(1, 0, 0) Local $hTexture = $aResult[7] $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0) If @error Then Return SetError(2, 0, 0) Local $hImage = $aResult[6] Local $hGfxCtxt = _GDIPlus_ImageGetGraphicsContext($hImage) _GDIPlus_GraphicsSetSmoothingMode($hGfxCtxt, 2) DllCall($ghGDIPDll, "uint", "GdipSetPixelOffsetMode", "handle", $hGfxCtxt, "int", 2) _GDIPlus_GraphicsFillEllipse($hGfxCtxt, 0, 0, $iWidth, $iHeight, $hTexture) _GDIPlus_BrushDispose($hTexture) _GDIPlus_GraphicsDispose($hGfxCtxt) Return $hImage EndFunc Br, UEZ Edited December 17, 2012 by UEZ genius257 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
genius257 Posted December 18, 2012 Author Share Posted December 18, 2012 That's perfect! Though the shape doesn't have to be an ellipse, this is perfect and I'll look into it Fast and neat, thank you! My highlighted topics: AutoIt Package Manager, AutoItObject Pure AutoIt, AutoIt extension for Visual Studio Code Github: AutoIt HTTP Server, AutoIt HTML Parser Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now