请翻译一个C函数,写成d的 ( 积分: 100 )

  • 主题发起人 主题发起人 deepfar
  • 开始时间 开始时间
D

deepfar

Unregistered / Unconfirmed
GUEST, unregistred user!
#include "stdAfx.h"
#include "Image.h"

// 从 BMP 文件中读取像素数组 ( 只支持 RGB24 真彩图 )
BYTE* LoadBmpFromFile(LPCTSTR strFileName, LONG& lWidth, LONG& lHeight)
{
HANDLE bmpFile = NULL;
bmpFile = CreateFile(strFileName, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (bmpFile == INVALID_HANDLE_VALUE)
return NULL;

DWORD dwRead = 0;
BITMAPFILEHEADER bfh = { NULL };

ReadFile(bmpFile, &bfh, sizeof(BITMAPFILEHEADER), &dwRead, NULL);
if (bfh.bfType != 0x4d42)
{
CloseHandle(bmpFile);
return NULL;
}

BITMAPINFOHEADER bih = { NULL };
ReadFile(bmpFile, &bih, sizeof(BITMAPINFOHEADER), &dwRead, NULL);
if (bih.biBitCount != 24)
{
CloseHandle(bmpFile);
return NULL;
}

UINT bmpSize = bih.biHeight * WIDTHBYTES(bih.biWidth * bih.biBitCount);
BYTE* imageBuf = new BYTE[bmpSize];
ReadFile(bmpFile, imageBuf, bmpSize, &dwRead, NULL);
if (dwRead != bmpSize)
{
delete [] imageBuf;
imageBuf = NULL;
}

CloseHandle(bmpFile);

lWidth = bih.biWidth;
lHeight = bih.biHeight;

return imageBuf;
}
 
function LoadBmpFromFile(const strFileName: string; var lWidth, lHeight: Cardinal):PByte;
var
bmpFile: THandle;
dwRead, bmpSize: DWord;
bfh : BITMAPFILEHEADER;
bih : BITMAPINFOHEADER;
imageBuf: PByte;
function WIDTHBYTES(const dwByteLen: Integer):Integer;
begin
Result := dwByteLen + (dwByteLen mod sizeof(DWORD));
end;
begin
Result := nil;
bmpFile := CreateFile(PChar(strFileName), GENERIC_READ, FILE_SHARE_READ,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (bmpFile = INVALID_HANDLE_VALUE) then
Exit;

dwRead := 0;
ReadFile(bmpFile, bfh, sizeof(BITMAPFILEHEADER), dwRead, nil);
if (bfh.bfType <> $4d42) then
begin
CloseHandle(bmpFile);
Exit;
end;

ReadFile(bmpFile, bih, sizeof(BITMAPINFOHEADER), dwRead, nil);
if (bih.biBitCount <> 24) then
begin
CloseHandle(bmpFile);
Exit;
end;

bmpSize := bih.biHeight * WIDTHBYTES(bih.biWidth * bih.biBitCount);
imageBuf := AllocMem(bmpSize);
ReadFile(bmpFile, imageBuf^, bmpSize, dwRead, nil);
if (dwRead <> bmpSize) then
begin
FreeMem(imageBuf);
imageBuf := nil;
end;

CloseHandle(bmpFile);

lWidth := bih.biWidth;
lHeight := bih.biHeight;

Result := imageBuf;
end;
 
学习,遇到高手了
 
读取象素而已, Delphi 自带的好得很,而且也没有 24bit 限制,还翻译个啥。
 
To: Miros

有一处有点问题,还请继续指教
bmpSize := bih.biHeight * WIDTHBYTES(bih.biWidth * bih.biBitCount);
imageBuf := AllocMem(bmpSize);
ReadFile(bmpFile, imageBuf^, bmpSize, dwRead, nil);
if (dwRead <> bmpSize) then
begin
FreeMem(imageBuf);
imageBuf := nil;
end;

这个地方总会 dwRead 不等于 bmpSize
 
msdn对readFile的标注:
lpNumberOfBytesRead
[out] A pointer to the variable that receives the number of bytes read
readFile 的第四个参数为应该为指针,表示读出的字节数.
改为:
ReadFile(bmpFile, imageBuf^, bmpSize, &amp;dwRead, nil);
//===================
lz看看
 
to: baiduan
不对,语法通不过
 
好久不用了,忘了D把API包装过....抱歉

bmp文件头结构字段含义:
biSize 结构BITMAPINFOHEADER的字节数,即sizeof(BITMAPINFOHEADER)*
biWidth
以像素为单位的图像宽度*
biHeight
以像素为单位的图像长度*
biplanes
目标设备的位平面数
biBitCount
每个像素的位数*(1)
biCompression
图像的压缩格式(这个值几乎总是为0)
biSizeImage
以字节为单位的图像数据的大小(对BI_RGB压缩方式而言)
biXPelsPermeter
水平方向上的每米的像素个数
biYpelsPerMeter
垂直方向上的每米的像素个数
biClrused
调色板中实际使用的颜色数(2)
biClrImportant
现实位图时必须的颜色数(3)

=============================
简单测了下,这段c代码有问题.
这里:
UINT bmpSize = bih.biHeight * WIDTHBYTES(bih.biWidth * bih.biBitCount);
BYTE* imageBuf = new BYTE[bmpSize];
ReadFile(bmpFile, imageBuf, bmpSize, &amp;dwRead, NULL);
if (dwRead != bmpSize)
{
delete [] imageBuf;
imageBuf = NULL;
}
这段代码意思是:如果读入的大小不等于bmp文件的实际大小,就出错处理.
实际上他计算出来bmpSize 的大小是错误的...

Delphi代码应该改为:
bmpsize:=bih.biHeight*bih.biWidth*(bih.biBitCount div 8);//仅适合BMP文件
imageBuf := AllocMem(bmpSize);
ReadFile(bmpFile, imageBuf^, bmpSize, dwRead, nil);
if (dwRead <> bmpSize) then
或者:
bmpsize:=bih.biSizeImage;
imageBuf := AllocMem(bmpSize);
ReadFile(bmpFile, imageBuf^, bmpSize, dwRead, nil);
if (dwRead <> bmpSize) then
//看看
 
后退
顶部