Jump to content

how to set transparent color for picture?


E1M1
 Share

Recommended Posts

  • Moderators

E1M1,

I believe you will have to create/recreate your image with a transparent background. But most paint programmes (other than MS Paint) can do that easily. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Most applications store bmp-files without any alpha channel (24-bit). You should use PNG. Make sure you have it set to 32-bit and you're set to go ;)

Link to comment
Share on other sites

Note however that GUICtrlCreate doesn't support png's. Search the forum for solutions (png transparency is a good string).

If you wish to use GUICtrlCreatePic with transparency you have to use gif's which I do not recomend because gif's are an abomination from the 90s so they doesn't have useless (see irony) features like bpp over 8.

edit:

@playlet

And especially don't forget _GdiPlus_ImageDispose().

Edited by monoceres

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

I just triet playlet's solution and I got

D:\My Documents\mario\mario.au3(137,54) : WARNING: $AC_SRC_ALPHA: possibly used before declaration.
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\My Documents\mario\mario.au3(137,54) : ERROR: $AC_SRC_ALPHA: undeclared global variable.
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\My Documents\mario\mario.au3 - 1 error(s), 1 warning(s)
!>17:56:22 AU3Check ended.rc:2

+ I cant find how to save transparent color in png image using infarnview or gimp.

Can I define transparentcolor for picture in Autoit?

In Blitz Basic

I just use

MaskImage hImage,153,217,234

if am windering if autoit can do that too.

Edited by E1M1

edited

Link to comment
Share on other sites

Hi, you can set individual colours to transparent in an image using the below function. It can be somewhat slow so may not be what you are looking for. See my signature for the outlook widget where I demonstrate using this function.

$object = ImageColorToTransparent($object, 0, 0, $iW,$iH, 0x668888); 0x000000 - Black

;$iColor - Colour to be made transparent. Hex colour format 0xRRGGBB. If Default used then top left pixel colour of image
; is used as the transparent colour.
Func ImageColorToTransparent($hImage2, $iStartPosX = 0, $iStartPosY = 0, $GuiSizeX = Default, $GuiSizeY = Default, $iColor = Default)
    Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value, $iIW, $iIH
    $iIW = _GDIPlus_ImageGetWidth($hImage2)
    $iIH = _GDIPlus_ImageGetHeight($hImage2)
    If $GuiSizeX = Default Or $GuiSizeX > $iIW - $iStartPosX Then $GuiSizeX = $iIW - $iStartPosX
    If $GuiSizeY = Default Or $GuiSizeY > $iIH - $iStartPosY Then $GuiSizeY = $iIH - $iStartPosY
    $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, $iStartPosX, $iStartPosY, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB)
    If $iColor = Default Then $iColor = GDIPlus_BitmapGetPixel($hBitmap1, 1, 1); Transparent color
    $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
;Get the returned values of _GDIPlus_BitmapLockBits ()
    $width = DllStructGetData($Reslt, "width")
    $height = DllStructGetData($Reslt, "height")
    $stride = DllStructGetData($Reslt, "stride")
    $format = DllStructGetData($Reslt, "format")
    $Scan0 = DllStructGetData($Reslt, "Scan0")
    For $i = 0 To $GuiSizeX - 1
        For $j = 0 To $GuiSizeY - 1
            $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4))
            $v_Value = DllStructGetData($v_Buffer, 1)
            If Hex($v_Value, 6) = Hex($iColor, 6) Then
                DllStructSetData($v_Buffer, 1, Hex($iColor, 6)); Sets Transparency here. Alpha Channel = 00, not written to.
            EndIf
        Next
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt)
    Return $hBitmap1
EndFunc  ;==>ImageColorToTransparent

;The GetPixel method gets the color of a specified pixel in this bitmap.
Func GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
    Local $tArgb, $pArgb, $aRet
    $tArgb = DllStructCreate("dword Argb")
    $pArgb = DllStructGetPtr($tArgb)
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb)
    Return "0x" & Hex(DllStructGetData($tArgb, "Argb"))
EndFunc  ;==>GDIPlus_BitmapGetPixel
Edited by picea892
Link to comment
Share on other sites

Try this.

#Include <GUIConstantsEx.au3>
#Include <Icons.au3>
#Include <WinAPIEx.au3>

Global Const $STM_SETIMAGE = 0x0172
Global Const $STM_GETIMAGE = 0x0173

Global Const $sFront = @TempDir & '\~wall.png'
Global Const $sBack = @TempDir & '\~logo.png'

Global $hForm, $Msg, $Slider, $Pic, $hPic, $hFront, $hBack

InetGet('http://www.autoitscript.com/forum/public/style_images/autoit/logo.png', $sFront)
InetGet('http://www.autoitscript.com/autoit3/files/graphics/autoit_matrix_wall_800x600.jpg', $sBack)

$hFront = _Icons_Bitmap_Crop(_Icons_Bitmap_Load($sFront), 0, 7, 465, 93)
$hBack = _Icons_Bitmap_Crop(_Icons_Bitmap_Load($sBack), 118, 200, 565, 200)

$hForm = GUICreate('MyGUI', 565, 200 + 61)
$Slider = GUICtrlCreateSlider(10, 200 + 18, 565 - 20, 26)
GUICtrlSetLimit(-1, 255, 0)
GUICtrlSetData(-1, 255)
$Pic = GUICtrlCreatePic('', 0, 0, 565, 200)
$hPic = GUICtrlGetHandle(-1)

_SetAlpha(255)

GUISetState()

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $Slider
            _SetAlpha(GUICtrlRead($Slider))
    EndSwitch
WEnd

;FileDelete($sFront)
;FileDelete($sBack)

Func _SetAlpha($iAlpha)

    Local $hDC, $hDestDC, $hSrcDC, $hBitmap, $hObj

    $hDC = _WinAPI_GetDC($hPic)
    $hDestDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap = _WinAPI_DuplicateBitmap($hBack)
    _WinAPI_SelectObject($hDestDC, $hBitmap)
    $hSrcDC = _WinAPI_CreateCompatibleDC($hDC)
    _WinAPI_SelectObject($hSrcDC, $hFront)
    _WinAPI_AlphaBlend($hDestDC, 50, 50, 465, 93, $hSrcDC, 0, 0, 465, 93, $iAlpha, 0)
    _WinAPI_DeleteDC($hDestDC)
    _WinAPI_DeleteDC($hSrcDC)
    _WinAPI_ReleaseDC($hPic, $hDC)
    _WinAPI_DeleteObject(_SendMessage($hPic, $STM_SETIMAGE, 0, $hBitmap))
    $hObj = _SendMessage($hPic, $STM_GETIMAGE)
    If $hObj <> $hBitmap Then
        _WinAPI_FreeObject($hBitmap)
    EndIf
EndFunc   ;==>_SetAlpha

Icons.au3

WinAPIEx.au3

Link to comment
Share on other sites

@ picea892

I have no idea how to use that func :S

CAn some1 give example tha does it with file c:\pic.bmp.

Then I can clearly see how to use that func

@ Yashied

Ur script is nice example, ty but I stil need method that allows me draw only red circle (atm I have 20x20 image that has red circle on blue background, but I want draw inly that circle, how I do this?I want make all non 0x0000FF colors be transparent.

Edited by E1M1

edited

Link to comment
Share on other sites

Make sure that you have the correct colour code. I have included a bmp for you to test with.

#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WINAPI.au3>
_GDIPlus_Startup()
Global $Image1 = _GDIPlus_ImageLoadFromFile("test.bmp")
   $width=_GDIPlus_ImageGetWidth($Image1)
   $height=_GDIPlus_ImageGetHeight($Image1)
Global Const $AC_SRC_ALPHA = 1
$GUI = GUICreate("Example",$width,$height,-1,-1,$WS_POPUP)
$pic=GUICtrlCreatePic("",0,0,$width,$height)
GUISetState()
$Image1=ImageColorToTransparent($Image1, 0x000000)
Global $Graphic = _GDIPlus_GraphicsCreateFromHWND(GUICtrlGetHandle($pic))
_GDIPlus_GraphicsDrawImageRect($Graphic, $Image1,0,0,$width,$height)
    
While 1
    $MSG = GUIGetMsg()
    Switch $MSG
        Case -3
            Quit()
    EndSwitch
WEnd

Func Quit()
    _GDIPlus_ImageDispose($Image1)
    _GDIPlus_GraphicsDispose($Graphic)
    _GDIPlus_Shutdown()
    Exit
EndFunc


;$iColor - Colour to be made transparent. Hex colour format 0xRRGGBB. If Default used then top left pixel colour of image
; is used as the transparent colour.
Func ImageColorToTransparent($hImage2, $iColor = Default)
    Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value, $iIW, $iIH

    $GuiSizeX = _GDIPlus_ImageGetWidth($hImage2)
    $GuiSizeY = _GDIPlus_ImageGetHeight($hImage2)
    $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, 0, 0, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB)
    If $iColor = Default Then $iColor = GDIPlus_BitmapGetPixel($hBitmap1, 1, 1); Transparent color
    ProgressOn("","Processing", "0 percent", "", @DesktopHeight-80, 1)
    $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
;Get the returned values of _GDIPlus_BitmapLockBits ()
    $width = DllStructGetData($Reslt, "width")
    $height = DllStructGetData($Reslt, "height")
    $stride = DllStructGetData($Reslt, "stride")
    $format = DllStructGetData($Reslt, "format")
    $Scan0 = DllStructGetData($Reslt, "Scan0")
    For $i = 0 To $GuiSizeX - 1
        For $j = 0 To $GuiSizeY - 1
            $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4))
            $v_Value = DllStructGetData($v_Buffer, 1)
            If Hex($v_Value, 6) = Hex($iColor, 6) Then
                DllStructSetData($v_Buffer, 1, Hex($iColor, 6)); Sets Transparency here. Alpha Channel = 00, not written to.
            EndIf
        Next
        ProgressSet(Int(100 * $i / ($GuiSizeX)), Int(100 * $i / ($GuiSizeX)) & " percent")
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt)
    ProgressOff()
    Return $hBitmap1
EndFunc  ;==>ImageColorToTransparent

;The GetPixel method gets the color of a specified pixel in this bitmap.
Func GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
    Local $tArgb, $pArgb, $aRet
    $tArgb = DllStructCreate("dword Argb")
    $pArgb = DllStructGetPtr($tArgb)
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb)
    Return "0x" & Hex(DllStructGetData($tArgb, "Argb"))
EndFunc  ;==>GDIPlus_BitmapGetPixel

test.bmp

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...