如何从gdiplus :: bitmap中检索字节数组数据? [英] How to retrieve byte array data from gdiplus::bitmap ?

查看:71
本文介绍了如何从gdiplus :: bitmap中检索字节数组数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好。

我想从Gdiplus :: Bitmap中检索字节数组(图像数据)数据。

所以我输入如下代码。



Hi all.
I want to retrieve byte array(image data) data from Gdiplus::Bitmap.
So I typed as following code.

bool CMyImage::GetImagePointer(BYTE* pBuffer)
{
//Gdiplus::Bitmap* m_pBmp; defined.
	PixelFormat format;
	format = m_pBmp->GetPixelFormat();
	int bpp = GetPixelFormatSize(format);
	int w = m_pBmp->GetWidth();
	int h = m_pBmp->GetHeight();
	int size = w*h*bpp/8;

	BitmapData data;
	Rect rect(0,0,w,h);
	m_pBmp->LockBits(&rect,ImageLockModeRead,format,&data);

	BYTE* pSrcPointer = (BYTE*)data.Scan0;
	BYTE* pDstPointer = pBuffer;
	
	int imageRowSize = w*bpp/8;
	for ( int i=0; i<h; i++ )
	{
		memcpy( pDstPointer, pSrcPointer, imageRowSize );
		pSrcPointer += w;
		pDstPointer += imageRowSize;
	}
	
	m_pBmp->UnlockBits(&data); 

	return true;
}





(Q)

但是如果图像的宽度大小(字节数组)不是4的倍数,位图图像不会校正对齐。



是什么原因?



请告诉我。



谢谢。



我的尝试:



如果它修改如下代码,图像对齐是正确的。

但位图上最多1行的底线是无数据。





(Q)
But If width size of a image(byte array) is not multiples of 4, bitmap image doesn't correcte alignment.

What is the reason?

Please advise me.

Thank you.

What I have tried:

If It modify as following code, image alignment is correct.
But 1 line at most bottom on bitmap is no data.

bool CMyImage::GetImagePointer(BYTE* pBuffer)
{
//Gdiplus::Bitmap* m_pBmp; defined.
	PixelFormat format;
	format = m_pBmp->GetPixelFormat();
	int bpp = GetPixelFormatSize(format);
	int w = m_pBmp->GetWidth();
	int h = m_pBmp->GetHeight();
	int size = w*h*bpp/8;

	BitmapData data;
	Rect rect(0,0,w,h);
	m_pBmp->LockBits(&rect,ImageLockModeRead,format,&data);

        memcpy(pBuffer, (BYTE*)data.Scan0, size);
        /*
	BYTE* pSrcPointer = (BYTE*)data.Scan0;
	BYTE* pDstPointer = pBuffer;
	
	int imageRowSize = w*bpp/8;
	for ( int i=0; i<h; i++ )
	{
		memcpy( pDstPointer, pSrcPointer, imageRowSize );
		pSrcPointer += w;
		pDstPointer += imageRowSize;
	}
        */
	
	m_pBmp->UnlockBits(&data); 

	return true;
}

推荐答案

Quote:

是什么原因?

它被称为 stride

来自 DIB及其在MSDN上的使用 [ ^ ]:



It is called stride.
From DIBs and Their Use at MSDN[^]:



biSizeImage 包含以字节为单位的位图大小或值0.值为0表示DIB具有默认大小。计算位图的大小并不困难:


biSizeImage Contains the size of the bitmap proper in bytes or the value 0. A value of 0 indicates that the DIB is of default size. Calculating the size of a bitmap is not difficult:
biSizeImage = ((((biWidth * biBitCount) + 31) &
~31) >> 3) * biHeight; 



疯狂的舍入和转移会导致位图在每条扫描线的末尾都是DWORD对齐的。当非零时,该字段告诉应用程序DIB的位需要多少存储空间。在处理RLE位图时,biSizeImage字段确实很有用,其大小取决于位图的编码程度。如果要传递RLE位图,则必须使用biSizeImage字段。


The crazy roundoffs and shifts account for the bitmap being DWORD-aligned at the end of every scanline. When nonzero, this field tells an application how much storage space the DIB's bits need. The biSizeImage field really becomes useful when dealing with an RLE bitmap, the size of which depends on how well the bitmap was encoded. If an RLE bitmap is to be passed around, the biSizeImage field is mandatory.


BitmapData类(Windows) [ ^ ]提供 Stride 成员它保存每行的字节数。



使用它来代替计算它。您还将 w 添加到 pSrcPointer 而不是行大小:

The BitmapData class (Windows)[^] provides the Stride member which holds the number of bytes per line.

Use this instead calculating it. You also added w to pSrcPointer instead of the row size:
int srcRowSize = std::abs(data.Stride);
// Which size to use for the destination depends on your usage.
// When calculating you must adjust for odd results
int imageRowSize = w*bpp/8;
if ((w*bpp) % 8)
    imageRowSize++;
for (int i=0; i<h; i++ )
{
    memcpy( pDstPointer, pSrcPointer, imageRowSize );
    // Add srcRowSize here instead of w
    //pSrcPointer += w;
    pSrcPointer += srcRowSize;
    pDstPointer += imageRowSize;
}



一次复制所有图像位时,您可以获得以下尺寸:


When copying all image bits at once you get the size by:

int size = data.Height * std::abs(data.Stride);


这篇关于如何从gdiplus :: bitmap中检索字节数组数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆