达人高手指点一下,关于delphi调用VC开发图像处理模块dll,参数传递问题
时间:2011-11-20
来源:互联网
在VC中导出函数实现如下
// 图像镜像导出函数
int _stdcall MirrorBmp(HDC hdcSrc,HBITMAP hbmpSrc,HDC hdcDest,BOOL bDirection)
{
//得到图象大小信息
int cx,cy;
//MessageBox(0,&"kdd",&"kdd",NULL);
//读取DIB信息
LPBYTE lpDIB=DIBfromBitmap(hdcSrc,hbmpSrc);
// MessageBox(0,&"dd2",&"dd2",NULL);
if(lpDIB==NULL)
return -1;
//MessageBox(0,&"dd3",&"dd3",NULL);
LPBYTE lpDIBits =(LPBYTE)lpDIB+sizeof(BITMAPINFOHEADER) + ::PaletteSize((LPSTR)lpDIB);
//MessageBox(0,&"dd",&"dd",NULL);
BITMAPINFOHEADER * lpBmpih=(BITMAPINFOHEADER *)lpDIB;
cx=lpBmpih->biWidth;
cy=lpBmpih->biHeight;
//对DIB进行转换
if(!MirrorDIB((LPSTR)lpDIBits, cx, cy, bDirection))
return -2;
/**/
//将变化后的信息放到目的句柄
if(SetDIBitsToDevice(hdcDest,0,0,cx,cy,0,0,0,cy,lpDIBits,(BITMAPINFO*)lpDIB,DIB_RGB_COLORS)==0)
return -3;
return 1;
}
用delphi调用始终没有调试成功,代码如下
procedure TForm1.BitBtn1Click(Sender: TObject);
var
hdc1,hdc2:HDC;
hbitm:HBITMAP;
begin
//Self.Image2.Picture.Bitmap.Assign(self.Image1.Picture.Graphic);
// self.Image1.Picture.Bitmap.Assign(Self.Image2.Picture.Graphic);
hdc1:=Self.Image1.Picture.Bitmap.Canvas.Handle;
Self.Image1.Picture.Bitmap.PixelFormat := pf24bit;
hbitm:=Self.Image1.Picture.Bitmap.Handle;
hdc2:=Self.Canvas.Handle;
//////////
hdc1 := CreateCompatibleDC(Self.Image1.Picture.Bitmap.Canvas.Handle);
//hbitm := CreateCompatibleBitmap(Self.Image1.Picture.Bitmap.Canvas.Handle, Self.Image1.Picture.Bitmap.Width, Self.Image1.Picture.Bitmap.Height);
ShowMessage(IntToStr(Self.Image1.Picture.Bitmap.Width)+'X'+IntToStr(Self.Image1.Picture.Bitmap.Height));
//////////
Form1.Caption:= IntToStr(hdc1)+':'+IntToStr(hbitm);
SelectObject(hdc1,hbitm) ;
Self.Image2.Picture.Bitmap.Canvas.FillRect(Rect(0,0,Self.Image1.Picture.Bitmap.Width,Self.Image1.Picture.Bitmap.Height));
//hdc2 := Self.Image2.Picture.Bitmap.Canvas.Handle;
hdc2 := CreateCompatibleDC(Self.Image2.Picture.Bitmap.Canvas.Handle);
MirrorBmp(hdc1,hbitm,hdc2,true) ;
end;
其中image1中已加载有位图,引入dll导出数据声明是
function MirrorBmp(const hdcSrc:HDC;const hbmpSrc:HBITMAP; const hdcDest:HDC; bDirection:BOOL):Integer;stdcall;external 'GeoTrans.dll';
前期通过messagebox作为输出调试信息,输出dd2就over了,也就是DLL中的LPBYTE lpDIB=DIBfromBitmap(hdcSrc,hbmpSrc);函数调用失败了,通过VC的dll的调试,发现是此函数IBfromBitmap(hdcSrc,hbmpSrc)中的实现代码
LPBYTE WINAPI DIBfromBitmap(HDC hDC,HBITMAP hBitmap)
{
int cx,cy;
CString ss,ss2,ss3;
ss.Format("%d",hBitmap);
AfxMessageBox(ss);
ss2.Format("%d",hDC);
AfxMessageBox(ss2);
//得到图象的宽度和高度
BITMAP bmp;
ss3.Format("%d",sizeof(BITMAP));
AfxMessageBox(ss3);
//问题就出在下面这一句,从delphi到这里位图句柄值都是对的,就是没有拿位图对象,哪位达人指点是什么原因
if(GetObject(hBitmap,sizeof(BITMAP),&bmp)==0)
return NULL;
// MessageBox(NULL,ss,(LPSTR)(LPCTSTR)"hh",NULL);
cx=bmp.bmWidth;
cy=bmp.bmHeight;
//初始化BITMAPINFO信息
BITMAPINFO m_bmi;
m_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_bmi.bmiHeader.biPlanes=1;
m_bmi.bmiHeader.biBitCount = 24;
m_bmi.bmiHeader.biCompression = BI_RGB;
m_bmi.bmiHeader.biSizeImage = 0;
m_bmi.bmiHeader.biXPelsPerMeter = 0;
m_bmi.bmiHeader.biYPelsPerMeter = 0;
m_bmi.bmiHeader.biClrUsed = 0;
m_bmi.bmiHeader.biClrImportant = 0;
if (IS_WIN30_DIB(&m_bmi))
{
m_bmi.bmiHeader.biWidth=cx;
m_bmi.bmiHeader.biHeight=cy;
}
else
{
m_bmi.bmiHeader.biWidth=(unsigned short)cx;
m_bmi.bmiHeader.biHeight=(unsigned short)cy;
}
CString str,str2;
str.Format("%d",cx);
str2.Format("%d",cy);
//申请一段暂用空间用来得到图象容量信息
LPBYTE pTemp=(LPBYTE)::GlobalAlloc(GMEM_FIXED,sizeof(BITMAPINFOHEADER) +::PaletteSize((LPSTR)&m_bmi));
memcpy(pTemp,&m_bmi.bmiHeader,sizeof(BITMAPINFOHEADER));
MessageBox(NULL,(LPSTR)(LPCTSTR)"申请一段暂用空间用来得到图象容量信息"+str+"x"+str2,(LPSTR)(LPCTSTR)"hh",NULL);
//Get biSizeImage
if (GetDIBits(hDC, hBitmap, 0, (WORD)cy,
NULL, (BITMAPINFO*)pTemp, DIB_RGB_COLORS)==0)
{
int error=GetLastError();
return NULL;
}
MessageBox(NULL,(LPSTR)(LPCTSTR)"Get biSizeImage",(LPSTR)(LPCTSTR)"hh",NULL);
//重新申请一段空间用来存放所需的DIB数据
m_bmi.bmiHeader.biSizeImage=((BITMAPINFOHEADER*)pTemp)->biSizeImage;
LPBYTE pBmpInfo =(LPBYTE)::GlobalAlloc(GMEM_FIXED,sizeof(BITMAPINFOHEADER) + ::PaletteSize((LPSTR)&m_bmi) + m_bmi.bmiHeader.biSizeImage);
memcpy(pBmpInfo,pTemp,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD));
GlobalFree((HGLOBAL)pTemp);
MessageBox(NULL,(LPSTR)(LPCTSTR)"重新申请一段空间用来存放所需的DIB数据",(LPSTR)(LPCTSTR)"hh",NULL);
LPBYTE pBits =(LPBYTE)pBmpInfo+sizeof(BITMAPINFOHEADER) + ::PaletteSize((LPSTR)&m_bmi);
MessageBox(NULL,(LPSTR)(LPCTSTR)"重新申请一段空间用来存放所需的DIB数据",(LPSTR)(LPCTSTR)"hh",NULL);
//读入DIB数据
if (GetDIBits(hDC,hBitmap, 0,(WORD)m_bmi.bmiHeader.biHeight,
pBits, (BITMAPINFO*)pBmpInfo, DIB_RGB_COLORS)==0)
{
int error=GetLastError();
GlobalFree((HGLOBAL)pBmpInfo);
return NULL;
}
MessageBox(NULL,(LPSTR)(LPCTSTR)"重新申请一段空间用来存放所需的DIB数据,读入DIB数据",(LPSTR)(LPCTSTR)"hh",NULL);
//返回DIB起始地址
return pBmpInfo;
}
见上面的//问题就出在下面这一句,从delphi到这里位图句柄值都是对的,就是没有拿位图对象,哪位达人指点是什么原因
if(GetObject(hBitmap,sizeof(BITMAP),&bmp)==0)
return NULL;
未获到位图对象,直接返回了,哪位指点一下哈,是设备上下文句柄与位图句柄传参有问题,还是delphi这种调用方式,传参方式有问题?
另外也说一下VB中的调用这样写的又是OK的,不知delphi的调用有什么不一样?见VB代码
导入DLL的函数声明
Private Declare Function MirrorBmp Lib "GeoTrans.dll" (ByVal hdcSrc As Long, ByVal hbmpSrc As Long, ByVal hDCDest As Long, ByVal bDirection As Boolean) As Integer
调用
Dim hDCDest As Long, hBmpDest As Long
Dim result As Integer
' hDCDest = CreateCompatibleDC(Picture2.hDC)
' hBmpDest = CreateCompatibleBitmap(Picture2.hDC, picWidth, picHeight)
'水平镜象 ON_GEOM_MIRX
' SelectObject hDCDest, hBmpDest
Picture2.Cls
result = MirrorBmp(Picture1.hDC, Picture1.Image.Handle, Picture2.hDC, True)
' BitBlt Picture2.hDC, 0, 0, picWidth, picHeight, hDCDest, 0, 0, vbSrcCopy
If result <> 1 Then
MsgBox result
End If
// 图像镜像导出函数
int _stdcall MirrorBmp(HDC hdcSrc,HBITMAP hbmpSrc,HDC hdcDest,BOOL bDirection)
{
//得到图象大小信息
int cx,cy;
//MessageBox(0,&"kdd",&"kdd",NULL);
//读取DIB信息
LPBYTE lpDIB=DIBfromBitmap(hdcSrc,hbmpSrc);
// MessageBox(0,&"dd2",&"dd2",NULL);
if(lpDIB==NULL)
return -1;
//MessageBox(0,&"dd3",&"dd3",NULL);
LPBYTE lpDIBits =(LPBYTE)lpDIB+sizeof(BITMAPINFOHEADER) + ::PaletteSize((LPSTR)lpDIB);
//MessageBox(0,&"dd",&"dd",NULL);
BITMAPINFOHEADER * lpBmpih=(BITMAPINFOHEADER *)lpDIB;
cx=lpBmpih->biWidth;
cy=lpBmpih->biHeight;
//对DIB进行转换
if(!MirrorDIB((LPSTR)lpDIBits, cx, cy, bDirection))
return -2;
/**/
//将变化后的信息放到目的句柄
if(SetDIBitsToDevice(hdcDest,0,0,cx,cy,0,0,0,cy,lpDIBits,(BITMAPINFO*)lpDIB,DIB_RGB_COLORS)==0)
return -3;
return 1;
}
用delphi调用始终没有调试成功,代码如下
procedure TForm1.BitBtn1Click(Sender: TObject);
var
hdc1,hdc2:HDC;
hbitm:HBITMAP;
begin
//Self.Image2.Picture.Bitmap.Assign(self.Image1.Picture.Graphic);
// self.Image1.Picture.Bitmap.Assign(Self.Image2.Picture.Graphic);
hdc1:=Self.Image1.Picture.Bitmap.Canvas.Handle;
Self.Image1.Picture.Bitmap.PixelFormat := pf24bit;
hbitm:=Self.Image1.Picture.Bitmap.Handle;
hdc2:=Self.Canvas.Handle;
//////////
hdc1 := CreateCompatibleDC(Self.Image1.Picture.Bitmap.Canvas.Handle);
//hbitm := CreateCompatibleBitmap(Self.Image1.Picture.Bitmap.Canvas.Handle, Self.Image1.Picture.Bitmap.Width, Self.Image1.Picture.Bitmap.Height);
ShowMessage(IntToStr(Self.Image1.Picture.Bitmap.Width)+'X'+IntToStr(Self.Image1.Picture.Bitmap.Height));
//////////
Form1.Caption:= IntToStr(hdc1)+':'+IntToStr(hbitm);
SelectObject(hdc1,hbitm) ;
Self.Image2.Picture.Bitmap.Canvas.FillRect(Rect(0,0,Self.Image1.Picture.Bitmap.Width,Self.Image1.Picture.Bitmap.Height));
//hdc2 := Self.Image2.Picture.Bitmap.Canvas.Handle;
hdc2 := CreateCompatibleDC(Self.Image2.Picture.Bitmap.Canvas.Handle);
MirrorBmp(hdc1,hbitm,hdc2,true) ;
end;
其中image1中已加载有位图,引入dll导出数据声明是
function MirrorBmp(const hdcSrc:HDC;const hbmpSrc:HBITMAP; const hdcDest:HDC; bDirection:BOOL):Integer;stdcall;external 'GeoTrans.dll';
前期通过messagebox作为输出调试信息,输出dd2就over了,也就是DLL中的LPBYTE lpDIB=DIBfromBitmap(hdcSrc,hbmpSrc);函数调用失败了,通过VC的dll的调试,发现是此函数IBfromBitmap(hdcSrc,hbmpSrc)中的实现代码
LPBYTE WINAPI DIBfromBitmap(HDC hDC,HBITMAP hBitmap)
{
int cx,cy;
CString ss,ss2,ss3;
ss.Format("%d",hBitmap);
AfxMessageBox(ss);
ss2.Format("%d",hDC);
AfxMessageBox(ss2);
//得到图象的宽度和高度
BITMAP bmp;
ss3.Format("%d",sizeof(BITMAP));
AfxMessageBox(ss3);
//问题就出在下面这一句,从delphi到这里位图句柄值都是对的,就是没有拿位图对象,哪位达人指点是什么原因
if(GetObject(hBitmap,sizeof(BITMAP),&bmp)==0)
return NULL;
// MessageBox(NULL,ss,(LPSTR)(LPCTSTR)"hh",NULL);
cx=bmp.bmWidth;
cy=bmp.bmHeight;
//初始化BITMAPINFO信息
BITMAPINFO m_bmi;
m_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_bmi.bmiHeader.biPlanes=1;
m_bmi.bmiHeader.biBitCount = 24;
m_bmi.bmiHeader.biCompression = BI_RGB;
m_bmi.bmiHeader.biSizeImage = 0;
m_bmi.bmiHeader.biXPelsPerMeter = 0;
m_bmi.bmiHeader.biYPelsPerMeter = 0;
m_bmi.bmiHeader.biClrUsed = 0;
m_bmi.bmiHeader.biClrImportant = 0;
if (IS_WIN30_DIB(&m_bmi))
{
m_bmi.bmiHeader.biWidth=cx;
m_bmi.bmiHeader.biHeight=cy;
}
else
{
m_bmi.bmiHeader.biWidth=(unsigned short)cx;
m_bmi.bmiHeader.biHeight=(unsigned short)cy;
}
CString str,str2;
str.Format("%d",cx);
str2.Format("%d",cy);
//申请一段暂用空间用来得到图象容量信息
LPBYTE pTemp=(LPBYTE)::GlobalAlloc(GMEM_FIXED,sizeof(BITMAPINFOHEADER) +::PaletteSize((LPSTR)&m_bmi));
memcpy(pTemp,&m_bmi.bmiHeader,sizeof(BITMAPINFOHEADER));
MessageBox(NULL,(LPSTR)(LPCTSTR)"申请一段暂用空间用来得到图象容量信息"+str+"x"+str2,(LPSTR)(LPCTSTR)"hh",NULL);
//Get biSizeImage
if (GetDIBits(hDC, hBitmap, 0, (WORD)cy,
NULL, (BITMAPINFO*)pTemp, DIB_RGB_COLORS)==0)
{
int error=GetLastError();
return NULL;
}
MessageBox(NULL,(LPSTR)(LPCTSTR)"Get biSizeImage",(LPSTR)(LPCTSTR)"hh",NULL);
//重新申请一段空间用来存放所需的DIB数据
m_bmi.bmiHeader.biSizeImage=((BITMAPINFOHEADER*)pTemp)->biSizeImage;
LPBYTE pBmpInfo =(LPBYTE)::GlobalAlloc(GMEM_FIXED,sizeof(BITMAPINFOHEADER) + ::PaletteSize((LPSTR)&m_bmi) + m_bmi.bmiHeader.biSizeImage);
memcpy(pBmpInfo,pTemp,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD));
GlobalFree((HGLOBAL)pTemp);
MessageBox(NULL,(LPSTR)(LPCTSTR)"重新申请一段空间用来存放所需的DIB数据",(LPSTR)(LPCTSTR)"hh",NULL);
LPBYTE pBits =(LPBYTE)pBmpInfo+sizeof(BITMAPINFOHEADER) + ::PaletteSize((LPSTR)&m_bmi);
MessageBox(NULL,(LPSTR)(LPCTSTR)"重新申请一段空间用来存放所需的DIB数据",(LPSTR)(LPCTSTR)"hh",NULL);
//读入DIB数据
if (GetDIBits(hDC,hBitmap, 0,(WORD)m_bmi.bmiHeader.biHeight,
pBits, (BITMAPINFO*)pBmpInfo, DIB_RGB_COLORS)==0)
{
int error=GetLastError();
GlobalFree((HGLOBAL)pBmpInfo);
return NULL;
}
MessageBox(NULL,(LPSTR)(LPCTSTR)"重新申请一段空间用来存放所需的DIB数据,读入DIB数据",(LPSTR)(LPCTSTR)"hh",NULL);
//返回DIB起始地址
return pBmpInfo;
}
见上面的//问题就出在下面这一句,从delphi到这里位图句柄值都是对的,就是没有拿位图对象,哪位达人指点是什么原因
if(GetObject(hBitmap,sizeof(BITMAP),&bmp)==0)
return NULL;
未获到位图对象,直接返回了,哪位指点一下哈,是设备上下文句柄与位图句柄传参有问题,还是delphi这种调用方式,传参方式有问题?
另外也说一下VB中的调用这样写的又是OK的,不知delphi的调用有什么不一样?见VB代码
导入DLL的函数声明
Private Declare Function MirrorBmp Lib "GeoTrans.dll" (ByVal hdcSrc As Long, ByVal hbmpSrc As Long, ByVal hDCDest As Long, ByVal bDirection As Boolean) As Integer
调用
Dim hDCDest As Long, hBmpDest As Long
Dim result As Integer
' hDCDest = CreateCompatibleDC(Picture2.hDC)
' hBmpDest = CreateCompatibleBitmap(Picture2.hDC, picWidth, picHeight)
'水平镜象 ON_GEOM_MIRX
' SelectObject hDCDest, hBmpDest
Picture2.Cls
result = MirrorBmp(Picture1.hDC, Picture1.Image.Handle, Picture2.hDC, True)
' BitBlt Picture2.hDC, 0, 0, picWidth, picHeight, hDCDest, 0, 0, vbSrcCopy
If result <> 1 Then
MsgBox result
End If
作者: amixtugtf 发布时间: 2011-11-20
自已UP一下,待达人来分析一下
作者: amixtugtf 发布时间: 2011-11-20
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28