Converting HBITMAP to imageData/alphaData?

Are you developing an External using the LiveCode Externals SDK?

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1005
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Converting HBITMAP to imageData/alphaData?

Post by trevordevore » Mon Oct 18, 2010 7:54 pm

I need to display an HBITMAP in a LiveCode image object. I was wondering if anyone had C/C++ code they would be willing to share that converts an HBITMAP on Windows to ARGB values that can be used with imageData and A values to be used with alphaData?

Thanks.
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 1005
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: Converting HBITMAP to imageData/alphaData?

Post by trevordevore » Fri Dec 10, 2010 7:27 pm

Here are the relevant parts of what I ended up doing:

Code: Select all

ExternalString theImgData;
char *newAlphaData = NULL;
char *newImageData = NULL;
const char *t_error;
int r_success;
Status st = Ok;

t_error = NULL;

// Initialize GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR           _gdiplusToken;

st = GdiplusStartup(&_gdiplusToken, &gdiplusStartupInput, NULL);
if (st != Ok) t_error = "unable to start gdi+";

if (t_error == NULL)
	// Note: iconBitmapWhite is a HBITMAP you created somehow
	Bitmap* bmpIconWhite = new Bitmap(iconBitmapWhite, NULL);
	Status st = bmpIconWhite->GetLastStatus();

	if (st == Ok)
	{
		BitmapData dataW;
		Rect rect(0, 0, bmpIconWhite->GetWidth(), bmpIconWhite->GetHeight());
		st = bmpIconWhite->LockBits(&rect, ImageLockModeRead, PixelFormat32bppPARGB, &dataW);
		if (st == Ok)
			{
				width = dataW.Width;
				height = dataW.Height;

				// Allocate memory for image/alphaData
				newAlphaData = (char*)malloc( (int)(width * height) );
				newImageData = (char*)malloc( (int)(width * height * 4) );

				unsigned char* pW; // holds the pixel
				unsigned char* pB;
				int y,x,i=0,j=0;
				
				for (y = 0; y < (int)dataW.Height; y++)
				{
					pW = ((unsigned char*) dataW.Scan0) + (y * dataW.Stride);
					pB = ((unsigned char*) dataB.Scan0) + (y * dataB.Stride);

					for (x = 0; x < (int)dataW.Width; x++, pW+=4, pB+=4, i++, j+=4)
					{
						newImageData[j] = 0;
						newImageData[j+1] = pW[2];
						newImageData[j+2] = pW[1];
						newImageData[j+3] = pW[0];
						newAlphaData[i] = abs((int)pW[0] - (int)pB[0] - (int)255);
					}
				}
				
				// Assign to "imageData" and "alphaData" keys of array variable in LiveCode
				// variable name was passed in as first argument.
				theImgData.buffer = newImageData;
				theImgData.length = height * width * 4;
				SetVariableEx( p_arguments[0], "imageData", &theImgData, &r_success);
				if (r_success == EXTERNAL_FAILURE)
				{
					t_error = "unable to store image data";
				}

				if (t_error == NULL)
				{
					theImgData.buffer = newAlphaData;
					theImgData.length = height * width;
					SetVariableEx( p_arguments[0], "alphaData", &theImgData, &r_success);
					if (r_success == EXTERNAL_FAILURE)
					{
						t_error = "unable to store alpha data";
					}
				}

				bmpIconWhite->UnlockBits(&dataW);
				
				if (newAlphaData) free(newAlphaData);
				if (newImageData) free(newImageData);
			}
		}
	}
	
	if (bmpIconWhite) delete bmpIconWhite;
	if (iconBitmapWhite) DeleteObject(iconBitmapWhite);
}

GdiplusShutdown(_gdiplusToken);
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

Post Reply

Return to “Building Externals”