Re: bitmap from clipboard to file

"Jon" <jonathangdavies-XZoyATsUNX5Wk0Htik3J/[email protected]>
Newsgroups gmane.comp.windows.wtl
Message-ID <[email protected]>
Hi,
Here's my (error handling stripped) file save method which I remember testing on various, but not all types of bitmap at the time, maybe you can see something in this that might help?

Jonathan

	BITMAPINFO  *pInfo;
	UINT8       *pImage;
	HANDLE      hFile;
	DWORD       i,LineSize,Offs;
	BITMAPFILEHEADER fh;
	BITMAPINFOHEADER bmi;

	// Get image information from our connected view
	pImage=GetImage();
	pInfo=GetBitmapInfo();

	
	hFile = CreateFile(lpszFilename, GENERIC_READ | GENERIC_WRITE, (DWORD)0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	
	// Copy Bitmapinfoheader (set Width and Height absolute)
	bmi=pInfo->bmiHeader;
	bmi.biWidth=abs(pInfo->bmiHeader.biWidth);
	bmi.biHeight=abs(pInfo->bmiHeader.biHeight);

	// Build fileheader and write
	fh.bfType=BMTYPE;
	BITMAPFILEHEADER bmFileHeader;
	bmFileHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + bmi.biSize + bmi.biClrUsed * sizeof(RGBQUAD) + bmi.biSizeImage; 

	if(pInfo->bmiHeader.biBitCount==8)
	{
		fh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
				 256*sizeof(RGBQUAD);
		fh.bfSize=fh.bfOffBits+pInfo->bmiHeader.biSizeImage;
		bmi.biClrUsed=256;
		bmi.biClrImportant=0;
	}
	else
	{
		fh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
		fh.bfSize   =fh.bfOffBits+pInfo->bmiHeader.biSizeImage;
		bmi.biClrUsed=0;
		bmi.biClrImportant=0;
	}

	fh.bfReserved1=0;
	fh.bfReserved2=0;

	// Write fileheader
	DWORD dwBytesWritten = 0;
	DWORD dwErr = 0;
	WriteFile(hFile, (LPVOID)&fh,sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);

	// Write bitmapinfoheader
	WriteFile(hFile, (char*)&bmi,sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);

	// Write Palette (only if grayscale)
	if(bmi.biClrUsed!=0)
	{
		WriteFile(hFile, (char*)pInfo->bmiColors,pInfo->bmiHeader.biClrUsed*sizeof(RGBQUAD), &dwBytesWritten, NULL);
		
	}

	// Write all lines (from bottom up)
	LineSize=bmi.biWidth*bmi.biBitCount/8;
	Offs=LineSize*(bmi.biHeight-1);
	for(i=0;i<(UINT32)bmi.biHeight;i++)
	{
		WriteFile(hFile, (char*)&pImage[Offs],LineSize, &dwBytesWritten, NULL);
		Offs-=LineSize;
	}

	CloseHandle(hFile);



--- In [email protected], "umeca74" <umeca74@...> wrote:
>
> Hi
> 
> I've been trying to save a window snapshot (32-bit) to a BMP file, but the saved image is slightly distorted, it looks like the picture is shifted to the right by a few pixels, like this:
> http://img97.imageshack.us/img97/5189/clipboard01e.png
> 
> here is the code i use (stripped from error checks). It must be something silly I do but after 2 days I can't see what!?
> 
> --------------------------------
> LPDATAOBJECT pDataObject;
> OleGetClipboard(&pDataObject);
> 
> FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
> STGMEDIUM stgm;
> pDataObject->GetData(&fmt, &stgm);
> file = root + _T("x2scrap.bmp");
> HANDLE hOut = CreateFile(file, GENERIC_WRITE, 0, NULL,
> CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
> 
> LPBITMAPINFOHEADER hDIB = (LPBITMAPINFOHEADER)GlobalLock(stgm.hGlobal);
> BITMAPFILEHEADER bmh; 
> DWORD sizebm = GlobalSize(stgm.hGlobal); // includes palettes 
> bmh.bfType = MAKEWORD('B', 'M');
> bmh.bfReserved1 = 0; 
> bmh.bfReserved2 = 0; 
> bmh.bfOffBits = sizeof(bmh) + hDIB->biSize; 
> 
> if(hDIB->biBitCount <= 8) { // palette exists
> DWORD tmp = hDIB->biClrUsed;
> if(!tmp)
> tmp = 1 << hDIB->biBitCount;
> 
> bmh.bfOffBits += tmp*sizeof(RGBQUAD);
> }
> 
> bmh.bfSize = sizebm + sizeof(bmh); 
> 
> DWORD ioAmount;
> WriteFile(hOut,&bmh,sizeof(bmh),&ioAmount,NULL);
> WriteFile(hOut,hDIB,sizebm,&ioAmount,NULL);
> 
> GlobalUnlock(stgm.hGlobal);
> CloseHandle(hOut);
> ReleaseStgMedium(&stgm);
> pDataObject->Release();
> --------------------------------
> 
> any help appreciated
> thanks
> nikos
>




------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/wtl/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/wtl/join
    (Yahoo! ID required)

<*> To change settings via email:
    mailto:[email protected] 
    mailto:[email protected]

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.