Before and after example
Function:
Code: Select all
/*
Gdip_ExpandColor grows the specified color by one pixel in all directions.
Helps remove fringe that can result when using a transparent color.
pBitMap is the pointer to your bitmap which will be modified directly
color parameter can be RGB or BGR and can include alpha channel or not.
Alpha channel will be added/changed to be 0xFF.
Example: Gdip_ExpandColor(pBitmap, 0xA024BA)
by boiler
2020-07-03
*/
Gdip_ExpandColor(pBitmap, color) {
if (A_PtrSize = 4)
expandColorMCodeBase64 := ""
. "2,x86:VYnlg+wQgU0MAAAA/8dF+AAAAADrWcdF/AEAAADrRItF"
. "+A+vRRCJwotF/AHQiUX0i0X0jRSFAAAAAItFCAHQiwA7RQx1GY"
. "tF9AX///8/jRSFAAAAAItFCAHCi0UMiQKDRfwBi0X8O0UQfLSD"
. "RfgBi0X4O0UUfJ/HRfgAAAAA61/HRfwAAAAA60eLRRArRfyJwo"
. "tF+A+vRRAB0IlF9ItF9AX///8/jRSFAAAAAItFCAHQiwA7RQx1"
. "FItF9I0UhQAAAACLRQgBwotFDIkCg0X8AYtFEIPoATtF/H+ug0"
. "X4AYtF+DtFFHyZx0X4AAAAAOtcx0X8AAAAAOtHi0UUK0X4D69F"
. "EInCi0X8AdCJRfSLRfSNFIUAAAAAi0UIAdCLADtFDHUZi1UQi0"
. "X0AdCNFIUAAAAAi0UIAcKLRQyJAoNF/AGLRfw7RRB8sYNF+AGL"
. "RRSD6AE7Rfh/mcdF+AEAAADrW8dF/AAAAADrRotF+A+vRRCJwo"
. "tF/AHQiUX0i0X0jRSFAAAAAItFCAHQiwA7RQx1G4tFEItV9CnC"
. "idCNFIUAAAAAi0UIAcKLRQyJAoNF/AGLRfw7RRB8soNF+AGLRf"
. "g7RRR8nZDJww=="
else
expandColorMCodeBase64 := ""
. "2,x64:VUiJ5UiD7BBIiU0QiVUYRIlFIESJTSiBTRgAAAD/x0X4"
. "AAAAAOtfx0X8AQAAAOtKi0X4D69FIInCi0X8AdCJRfSLRfRIjR"
. "SFAAAAAEiLRRBIAdCLADtFGHUci0X0g+gBicBIjRSFAAAAAEiL"
. "RRBIAcKLRRiJAoNF/AGLRfw7RSB8roNF+AGLRfg7RSh8mcdF+A"
. "AAAADrZcdF/AAAAADrTYtFICtF/InCi0X4D69FIAHQiUX0i0X0"
. "g+gBicBIjRSFAAAAAEiLRRBIAdCLADtFGHUXi0X0SI0UhQAAAA"
. "BIi0UQSAHCi0UYiQKDRfwBi0Ugg+gBO0X8f6iDRfgBi0X4O0Uo"
. "fJPHRfgAAAAA62THRfwAAAAA60+LRSgrRfgPr0UgicKLRfwB0I"
. "lF9ItF9EiNFIUAAAAASItFEEgB0IsAO0UYdR6LVSCLRfQB0InA"
. "SI0UhQAAAABIi0UQSAHCi0UYiQKDRfwBi0X8O0UgfKmDRfgBi0"
. "Uog+gBO0X4f5HHRfgBAAAA62PHRfwAAAAA606LRfgPr0UgicKL"
. "RfwB0IlF9ItF9EiNFIUAAAAASItFEEgB0IsAO0UYdSCLRSCLVf"
. "QpwonQicBIjRSFAAAAAEiLRRBIAcKLRRiJAoNF/AGLRfw7RSB8"
. "qoNF+AGLRfg7RSh8lZBIg8QQXcOQ"
expandColorMCode := BentschiMCode(expandColorMCodeBase64)
Gdip_GetImageDimensions(pBitmap, w, h)
Gdip_LockBits(pBitmap, 0, 0, w, h, stride, scan, bitmapData)
DllCall(expandColorMCode, "uint", scan, "uint", color, "int", w, "int", h, "cdecl")
Gdip_UnlockBits(pBitmap, bitmapData)
}
BentschiMCode(mcode)
{
static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
return
if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
return
p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
if (c="x64")
DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
return p
DllCall("GlobalFree", "ptr", p)
}
Demo:
Code: Select all
#Include <gdip_all>
#Include Gdip_ExpandColor.ahk
pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile("peter_griffin.png")
Gdip_ExpandColor(pBitmap, 0xc040c0)
Gdip_SaveBitmapToFile(pBitmap, "peter_griffin_trimmed.png")
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
Gui, +HwndGuiID
Gui, Color, c040c0
Gui, Add, Picture,, peter_griffin.png
Gui, Add, Picture, x+5 yp, peter_griffin_trimmed.png
Gui, Show
WinSet, TransColor, c040c0, ahk_id %GuiID%
return
Esc::ExitApp
Image used for demo
Source for MCode:
Code: Select all
unsigned int Gdip_ExpandColor(unsigned int *bitmap, unsigned int targetColor, int w, int h)
{
int x, y;
unsigned int p;
targetColor = targetColor | 0xFF000000; // add A channel
// replace all the colors to the left of the target color:
for (y = 0; y < h; ++y) {
for (x = 1; x < w; ++x) {
p = x + y * w;
if (bitmap[p] == targetColor)
bitmap[p - 1] = targetColor;
}
}
// replace all the colors to the right of the target color:
for (y = 0; y < h; ++y) {
for (x = 0; x < w - 1; ++x) {
p = w - x + y * w;
if (bitmap[p - 1] == targetColor)
bitmap[p] = targetColor;
}
}
// replace all the colors below the target color:
for (y = 0; y < h - 1; ++y) {
for (x = 0; x < w; ++x) {
p = x + (h - y) * w;
if (bitmap[p] == targetColor)
bitmap[p + w] = targetColor;
}
}
// replace all the colors above the target color:
for (y = 1; y < h; ++y) {
for (x = 0; x < w; ++x) {
p = x + y * w;
if (bitmap[p] == targetColor)
bitmap[p - w] = targetColor;
}
}
}