BITMAPINFO bh = {0};
int BytesPerLine;
bh.bmiHeader.biBitCount = 24;
bh.bmiHeader.biCompression = BI_RGB;
bh.bmiHeader.biWidth = bitmap.bmWidth;
bh.bmiHeader.biHeight = bitmap.bmHeight;
BytesPerLine =
4*((bitmap.bmWidth*bh.bmiHeader.biBitCount+31)/32);
bh.bmiHeader.biSizeImage = BytesPerLine * bitmap.bmHeight;
bh.bmiHeader.biPlanes = 1;
bh.bmiHeader.biSize = sizeof(bh.bmiHeader);
GetDIBits(hdcMem, hbmp, 0, 0, NULL, &bh,
DIB_RGB_COLORS); // 查询BITMAPINFO bits = new BYTE[ bh.bmiHeader.biSizeImage];
GetDIBits(hdcMem, hbmp, 0, bh.bmiHeader.biHeight , bits, &bh, DIB_RGB_COLORS);
// 获得整张位图的数据,保存到bits指向的空间
SetDIBits(hdc, bmp, 0, bh.bmiHeader.biHeight , bits, &bh, DIB_RGB_COLORS);
DrawPixel(hdcMem, bh.bmiHeader.biWidth, bh.bmiHeader.biHeight,
BytesPerLine, cxSource, 2);
BitBlt(hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, SRCCOPY);
CDC
memDc;
memDc.CreateCompatibleDC(GetDC());//创建内存DC CBitmap
memBmp;//生成内存位图
//此处使用GetDc为什么会失败呢
if
(!memBmp.CreateCompatibleBitmap(&memDc, iXPels,
iYPels))
return;
CBitmap* pOldBitmap =
memDc.SelectObject(&memBmp);//将数据写入位图 draw(memDc); //在内存位图中绘图
//贴图检验图像时存在的 //GetDC()->BitBlt(0, 0, boxRect.width(),
boxRect.height(), &memDc, 0, 0, SRCCOPY);
BITMAP
bmp;
memBmp.GetBitmap(&bmp);
int iWidth =
bmp.bmWidth;
int iHeight
= bmp.bmHeight;
long
lXPelsPerMeter, lYPelsPerMeter;
lXPelsPerMeter = iWidth / (int)boxRect.width() * 1000;
lYPelsPerMeter = iHeight / (int)boxRect.height() *
1000;
BITMAPINFO *pBmInfo = (BITMAPINFO *)(new BYTE
[sizeof(BITMAPINFOHEADER) + sizeof
(RGBQUAD) * 2]);
pBmInfo->bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
pBmInfo->bmiHeader.biWidth = iWidth;
//位图的宽度,单位为像素
pBmInfo->bmiHeader.biHeight = iHeight; //位图的高度
pBmInfo->bmiHeader.biPlanes = 1;
pBmInfo->bmiHeader.biBitCount =
1; //每个像素所需的位数
pBmInfo->bmiHeader.biCompression = BI_RGB;
pBmInfo->bmiHeader.biSizeImage = 0;
pBmInfo->bmiHeader.biXPelsPerMeter =
lXPelsPerMeter;
pBmInfo->bmiHeader.biYPelsPerMeter =
lYPelsPerMeter;
pBmInfo->bmiHeader.biClrImportant = 0;
pBmInfo->bmiHeader.biClrUsed =
2; //设置使用的颜色数
pBmInfo->bmiColors[0].rgbRed = 0; //设置颜色
pBmInfo->bmiColors[0].rgbGreen = 0;
pBmInfo->bmiColors[0].rgbBlue =
0;
pBmInfo->bmiColors[0].rgbReserved = 0;
pBmInfo->bmiColors[1].rgbRed = 255;
pBmInfo->bmiColors[1].rgbGreen = 255;
pBmInfo->bmiColors[1].rgbBlue =
255;
pBmInfo->bmiColors[1].rgbReserved = 0;
void*
pArray = NULL;
HBITMAP hbmp
= CreateDIBSection(NULL, pBmInfo, DIB_RGB_COLORS,
&pArray, NULL, 0);
//ASSERT(hbmp != NULL);
//生成位图
if(hbmp !=
NULL)
{ int iHeadInfoSize = sizeof(BITMAPINFOHEADER) + 2
*
sizeof(RGBQUAD);//信息头大小 int iDataSize = ((iWidth /8 + 3) / 4) *
4; //iDataSize = bmp.bmWidthBytes * iHeight;//图像数据大小
int iTotalBytes = iHeadInfoSize +
iDataSize; BYTE *pByteBuff = new
BYTE[iTotalBytes]; memset(pByteBuff, 255, iTotalBytes);
memcpy(pByteBuff, pBmInfo,
iHeadInfoSize);//拷贝头信息 BYTE *pBits = pByteBuff + iHeadInfoSize; //将指针移动到数据区
memBmp.GetBitmapBits(iDataSize, pBits);//拷贝图像数据
CString sFilePath =
_T("");//将CBitmap中的数据转到BYTE数组,然后存到CBBitmap中
CBPoint startPt(boxRect.left, boxRect.top);
iTotalBytes = iHeadInfoSize
+iDataSize; setContents(sFilePath, iTotalBytes, pByteBuff,
boxRect.width(),
boxRect.height(), startPt);
}
delete
pBmInfo;
如果我没理解错的话你就是想将位图的数据存盘
那通过GetBitmapBits就可以获取数据
然后你想通过这些数据再将位图恢复出来
那SetBitmapBits即可啊
可是你又是分析文件头又是分析位图结构
你到底是想做什么呢
你关心的不就是数据么
位图信息头和位图数据都是为了放在一个我们自定义的位图结构中用的
将这句话
memBmp.GetBitmapBits(iDataSize,
pBits);//拷贝图像数据
改为
memcpy(pBits, bmp.bmBits,iDataSize);
之后,就可以了
准备结贴
虽然还是很疑惑GetBitmapBits为什么会出错
//从外部读入数组参数。
void CTestactivxCtrl::testread(const VARIANT FAR&
buffer)
{
// TODO: Add
your dispatch handler code here
long dim=SafeArrayGetDim(buffer.parray);
long ubound;
long lbound;
SAFEARRAY
*psa;
psa =
buffer.parray;
SafeArrayGetUBound(psa,dim,&ubound);
SafeArrayGetLBound(psa,dim,&lbound);
double* buf;
double pd[40];
// CString
strtemp;
SafeArrayAccessData(psa,(void**)&buf);
for (int
i=lbound;i
{
pd[i]=buf[i];
strtemp = pd[i];
strtemp.Format("%f",pd[i]);
MessageBox(strtemp);
}
SafeArrayUnaccessData(psa);
// CString
a;
}
在VB中的代码,传入数组参数:
Private Sub Command2_Click()
Dim buf(3) As Double
buf(0) = 65
buf(1) = 23
buf(2) = 32
Testactivx1.testread buf
End Sub
//---------------------------------------------
//返回一个数组参数
void CTestactivxCtrl::retarray(VARIANT FAR* buffer)
{
// TODO: Add
your dispatch handler code here
//返回数组
SAFEARRAY FAR* psa;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound=0;
rgsabound[0].cElements=2;
psa=SafeArrayCreate(VT_I4,1,rgsabound);
long idx;
long setdt;
idx=0;
setdt=12;
SafeArrayPutElement(psa,&idx,&setdt);
idx=1;
setdt=342;
SafeArrayPutElement(psa,&idx,&setdt);
V_VT(buffer)
= VT_ARRAY|VT_I4;
V_ARRAY(buffer)=psa;
}
//在VB中的代码,传出数组参数:
Private Sub Command3_Click()
Dim rarr As Variant
Testactivx1.retarray rarr
MsgBox rarr(0) &
" " & rarr(1)
End Sub
以上代码是均在VC6.0 VB6.0下测试通过。
以前在别的地方见过一个通过调用系统API实现屏幕截图的例子,从内心来说我不太喜欢在C#代码中出现这种情况,现在什么都讲“和谐”,我觉得这种做法就是破坏了我们的“和谐”代码,呵呵,开玩笑,有的时候,不通过系统API确实难以做到的。
下面讲述的就是怎么通过纯C#来实现屏幕截图,代码如下:
//截取全屏图象
privatevoidbtnFullScreen_Click(objectsender,EventArgse)
{
//创建图象,保存将来截取的图象
Bitmapimage=newBitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);
GraphicsimgGraphics=Graphics.FromImage(image);
//设置截屏区域
imgGraphics.CopyFromScreen(0,0,0,0,newSize(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height));
//保存
SaveImage(image);
}
//保存图象文件
privatevoidSaveImage(Imageimage)
{
if(saveFileDialog.ShowDialog(this)==DialogResult.OK)
{
stringfileName=saveFileDialog.FileName;
stringextension=Path.GetExtension(fileName);
if(extension==".jpg")
{
image.Save(fileName,ImageFormat.Jpeg);
}
else
{
image.Save(fileName,ImageFormat.Bmp);
}
}
}
这段代码其实很简单,可以设置截屏区域的位置和大小,只不过只能在.net
2.0环境中才能运行。本人正在进一步完善实现拖动拖动截屏技术,类似于QQ中的截屏办法,正在攻关中,如果完成就向大家公布源代码。
VC中怎么读取bmp文件的像素?(2010-11-04 21:00:10)转载▼标签: it 分类: VC
编程 首先BMP文件包括两个部分:文件头和文件内容。我们可以得到公式:文件的字节长度=头文件的字节数+像素数。具体读取像素的思路以及代码如下:
第一步:判定文件是不是bmp文件。从文件里读取头文件,然后读取文件头的类型属性。
BITMAPFILEHEADER bmfHeader;
// 尝试读取DIB文件头
if (file.Read((LPSTR)&bmfHeader,
sizeof(bmfHeader)) != sizeof(bmfHeader))
{
// 大小不对,返回NULL。
return NULL;
}
// 判断是否是DIB对象,检查头两个字节是否是"BM"
if (bmfHeader.bfType != DIB_HEADER_MARKER)
{
// 非DIB对象,返回NULL。
return NULL;
}
第二步:用文件的字节数减去文件头的字节数后,读取后面的数据即是bmp的像素。
DWORD dwBitsSize;
HDIB hDIB;
LPSTR pDIB;
// 获取DIB(文件)长度(字节)
dwBitsSize = file.GetLength();
// 为DIB分配内存
hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE |
GMEM_ZEROINIT, dwBitsSize);
if (hDIB == 0)
{
// 内存分配失败,返回NULL。
return NULL;
}
// 锁定
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
// 读象素
if (file.ReadHuge(pDIB, dwBitsSize -
sizeof(BITMAPFILEHEADER)) !=
dwBitsSize - sizeof(BITMAPFILEHEADER) )
{
// 大小不对。
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 释放内存
::GlobalFree((HGLOBAL) hDIB);
// 返回NULL。
return NULL;
}
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
'从流转换为图像 Public Function StreamToPicture(ByVal Stream As IStream) As
StdPicture Dim
picStream As IStream Dim lBitmap
As Long Dim hBitmap
As Long Dim
lngGdipToken As Long Dim
tPictDesc As PICTDESC Dim
IID_IPicture As IID Dim oPicture
As IPicture lngGdipToken
=
StartUpGDIPlus(GdiPlusVersion) Set
picStream = Stream '从Stream加载Bitmap If
GdipLoadImageFromStream(picStream, lBitmap) = OK
Then '根据Bitmap创建hBitbmp If GdipCreateHBITMAPFromBitmap(lBitmap, hBitmap, 0) = OK
Then With tPictDesc .cbSizeOfStruct =
Len(tPictDesc) .picType =
vbPicTypeBitmap .hgdiObj = hBitmap .hPalOrXYExt = 0 End With ' 初始化IPicture With IID_IPicture .Data1 =
&H7BF80981 .Data2 =
&HBF32