Log in

View Full Version : Bitmap -ImageMagick help


4992
21st August 2003, 03:56
Hi,
I'm writing a program that takes images and turns them into AVI files, but I've been having problems with the actual image handling. I was told on here to try ImageMagick, and I have it working, where I can load images, and turn them into bitmaps. I'm coding in C.

The Problem:
My AVI handling routines, take BITMAPINFOHEADER structures to turn the images into AVI frames. What I've been able to piece together by the code below, only fills in a BITMAP structure.

As you can see below I have the Bitmap bits, but I can't figure out how to use this information to help me fill in the bitmapinfoheader.
I've tried to do a CopyMemory, but I'm not really all that great with coding, and don't know if I've done it all right.
I've also tried to use CreateDIBSection instead of CreateBitmapIndirect, so I can use the DIBSECTION structure later on the bitmap handle, and retrieve my BITMAPINFOHEADER.

Possible Solution:
Figure out how to fill in a BITMAPINFOHEADER structure with the information I have.

Really, I can't figure out how to do this. Thanks in Advance.

Here is my source.

HBITMAP *MagickLoadImage(PTSTR pstrFileName, UINT SizeX, UINT SizeY)
{
BITMAPINFOHEADER bmi;
unsigned long nPixels, nPixelCount;
long memSize;
const PixelPacket *pPixels;
BITMAP bitmap;
BYTE *pBits;
HBITMAP bitmapH;
HANDLE theBitsH;
ExceptionInfo exception;
Image *image, *resize_image;
ImageInfo *image_info;

GetExceptionInfo(&exception);
image_info=CloneImageInfo((ImageInfo *) NULL);
(void) strcpy(image_info->filename,pstrFileName);
image=ReadImage(image_info,&exception);

if (exception.severity != UndefinedException)
CatchException(&exception);

if (image == (Image *) NULL)
return NULL;

if (image->columns != SizeX || image->rows != SizeY) //Check to see if resizing is needed.
resize_image=ResizeImage(image,SizeX,SizeY,LanczosFilter,1,0,&exception);
else
resize_image = image;

if (resize_image == (Image *) NULL)
MagickError(exception.severity,exception.reason,exception.description);

//Turn the ImageMagick Image into a bitmap image.
nPixels = resize_image->columns * resize_image->rows;

bitmap.bmType = 0;
bitmap.bmWidth = resize_image->columns;
bitmap.bmHeight = resize_image->rows;
bitmap.bmWidthBytes = bitmap.bmWidth * 4;
bitmap.bmPlanes = 1;
bitmap.bmBitsPixel = 32;
bitmap.bmBits = NULL;

memSize = nPixels * bitmap.bmBitsPixel;
theBitsH = (HANDLE) GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, memSize);

if (theBitsH == NULL)
return NULL; // DoDisplayError( "OnEditCopy", GetLastError() );
else {
RGBQUAD * theBits = (RGBQUAD *) GlobalLock((HGLOBAL) theBitsH);
RGBQUAD *pDestPixel = theBits;
if ( bitmap.bmBits == NULL )
bitmap.bmBits = theBits;

pPixels = AcquireImagePixels(resize_image,0,0,resize_image->columns,resize_image->rows,&resize_image->exception);

for( nPixelCount = nPixels; nPixelCount ; nPixelCount-- )
{
pDestPixel->rgbRed = ScaleQuantumToChar(pPixels->red);
pDestPixel->rgbGreen = ScaleQuantumToChar(pPixels->green);
pDestPixel->rgbBlue = ScaleQuantumToChar(pPixels->blue);
pDestPixel->rgbReserved = 0;
++pDestPixel;
++pPixels;
}

bitmap.bmBits = theBits;
/*
//The bitmap info header
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biWidth = bitmap.bmWidth;
bmi.biHeight = bitmap.bmHeight;
bmi.biPlanes = 1;
bmi.biBitCount = 24;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = 0;
bmi.biXPelsPerMeter = 0;
bmi.biYPelsPerMeter = 0;
bmi.biClrUsed = 0;
bmi.biClrImportant = 0;

//bitmapH = CreateDIBSection(NULL, (BITMAPINFO *) &bmi, 0, &pBits, NULL, 0);

//CopyMemory(&pBits, theBitsH, sizeof(theBitsH));
*/
GlobalUnlock((HGLOBAL) theBitsH);
}

bitmapH = CreateBitmapIndirect( &bitmap );

DestroyImage(image);
DestroyImage(resize_image);
DestroyImageInfo(image_info);
DestroyExceptionInfo(&exception);

return bitmapH;

}

4992
25th August 2003, 04:59
Ok, I figured out that problem, but now I have another question. ImageMagick only outputs images in 32 bpp. I need to figure out how to use C code to change the bits per pixel (bpp) to 24 bits. My avi routines don't seem to handle 32 bits, and I don't really want to use them anyway, since most people I know don't have support for 32bit graphics.

DaveEL
26th August 2003, 16:53
Just drop ever 4th octet IIRC.

Something along of lines of

void* inputPointer=bitmapPointer;
void* outputPointer=bitmapPointer;

for(int foo=1;foo<numberofpixels;foo++) {
inputPointer+=4;
outputPointer+=3;
memcpy(outputPointer,inputPointer,3);
}

DaveEL

4992
29th August 2003, 05:13
Thanks, that did the trick for changing the bitmaps to 24bit. :)