小妹现在急着出结果,但问题迟迟不能解决,希望好心人帮我指点迷津啊,分数不够可以再加。
我要把两张的bmp叠加在一起,透明度可调,调节过程中会有渐显的结果。
在网上也查了很多,但都没有把问题解决,失望的不行,之前发过一次,没效果,只能再发一次了。如果有源码的话发在我邮箱,感谢。[email protected],我的qq:310731218.其实我的VC++基础不好的,但是因为老师要做这课题,就硬着头皮接下来了,到现在都快到尾声了,我还没搞出来,郁闷的很,我好爱埋怨啊!下面是我用slider控制图像叠加时透明度的代码 。
hDIB和hDIBSrc是成员变量,分别是图1和图2的句柄(已经在别的函数中得到)。IDC_PICCOMP是picture控件,我想让叠加后的图像在它里面显示。
编译过了,但运行不了,调试时到
int cxSrc=lpbmifh->biWidth; // 源图象宽度
int cySrc=lpbmifh->biHeight; // 源图象高度
这个位置就出错了。中间叠加的代码是在网上查的)
void CMy2009Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
CSliderCtrl* slider=(CSliderCtrl*) pScrollBar;
if (slider==&m_slider)
{
m_Alpha=slider->GetPos();
int alpha=m_Alpha; // BOOL CompoundDIB(HANDLE hDIB,HANDLE hDIBSrc,int alpha)
//{
LPVOID lpvBuf=NULL; // 目标图象数据指针
LPVOID lpvBufSrc=NULL; // 源图数据指针 // // 源图象信息 //
LPBITMAPINFO lpbmif=(LPBITMAPINFO)hDIBSrc;
LPBITMAPINFOHEADER lpbmifh=(LPBITMAPINFOHEADER)lpbmif;
// 计算图象数据偏移量
UINT nColors=lpbmifh->biClrUsed ? lpbmifh->biClrUsed : 1 < <lpbmifh->biBitCount;
if ( nColors >256 )
nColors=0; // 如果颜色数大于256色,则没有调色板
lpvBufSrc=(LPVOID)((LPBYTE)lpbmif->bmiColors+nColors*sizeof(RGBQUAD));
int cxSrc=lpbmifh->biWidth; // 源图象宽度
int cySrc=lpbmifh->biHeight; // 源图象高度
// 计算图象每行的字节数(图象位数 x 图象宽度,如果不能被2整除则在每行后面添加一个0字节)
int nBytesPerLineSrc=((cxSrc*lpbmifh->biBitCount+31)&~31)/8; // // 目标图象信息 //
lpbmif=(LPBITMAPINFO)hDIB;
lpbmifh=(LPBITMAPINFOHEADER)lpbmif;
nColors=lpbmifh->biClrUsed ? lpbmifh->biClrUsed : 1 < <lpbmifh->biBitCount;
if ( nColors >256 )
nColors=0;
lpvBuf=(LPVOID)((LPBYTE)lpbmif->bmiColors+nColors*sizeof(RGBQUAD));
int cx=lpbmifh->biWidth;
int cy=lpbmifh->biHeight;
int nBytesPerLine=((cx*lpbmifh->biBitCount+31)&~31)/8; LPBYTE lpbPnt=NULL;
LPBYTE lpbPntSrc=NULL;
// // 通过alpha值合并两张图象的像素值 //
// 这里假设是24位真彩色图象,其他深度的图象处理方法可以以次类推
for ( int y=(cy <cySrc ? cy : cySrc); y>0 ;y-- )
{
lpbPnt=(LPBYTE)lpvBuf+nBytesPerLine*(y-1);
lpbPntSrc=(LPBYTE)lpvBufSrc+nBytesPerLineSrc*(y-1);
for ( int x=0; x <(cx <cxSrc ? cx : cxSrc); x++ )
{
for ( int i=0 ;i <3 ;i++ )
*lpbPnt++=(*lpbPnt*(255-alpha)+*(lpbPntSrc++)*alpha)/255; } } CStatic* pPic=(CStatic*)GetDlgItem(IDC_PICCOMP); ASSERT(pPic);
pPic->SetBitmap((HBITMAP)hDIB); Invalidate();
我要把两张的bmp叠加在一起,透明度可调,调节过程中会有渐显的结果。
在网上也查了很多,但都没有把问题解决,失望的不行,之前发过一次,没效果,只能再发一次了。如果有源码的话发在我邮箱,感谢。[email protected],我的qq:310731218.其实我的VC++基础不好的,但是因为老师要做这课题,就硬着头皮接下来了,到现在都快到尾声了,我还没搞出来,郁闷的很,我好爱埋怨啊!下面是我用slider控制图像叠加时透明度的代码 。
hDIB和hDIBSrc是成员变量,分别是图1和图2的句柄(已经在别的函数中得到)。IDC_PICCOMP是picture控件,我想让叠加后的图像在它里面显示。
编译过了,但运行不了,调试时到
int cxSrc=lpbmifh->biWidth; // 源图象宽度
int cySrc=lpbmifh->biHeight; // 源图象高度
这个位置就出错了。中间叠加的代码是在网上查的)
void CMy2009Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
CSliderCtrl* slider=(CSliderCtrl*) pScrollBar;
if (slider==&m_slider)
{
m_Alpha=slider->GetPos();
int alpha=m_Alpha; // BOOL CompoundDIB(HANDLE hDIB,HANDLE hDIBSrc,int alpha)
//{
LPVOID lpvBuf=NULL; // 目标图象数据指针
LPVOID lpvBufSrc=NULL; // 源图数据指针 // // 源图象信息 //
LPBITMAPINFO lpbmif=(LPBITMAPINFO)hDIBSrc;
LPBITMAPINFOHEADER lpbmifh=(LPBITMAPINFOHEADER)lpbmif;
// 计算图象数据偏移量
UINT nColors=lpbmifh->biClrUsed ? lpbmifh->biClrUsed : 1 < <lpbmifh->biBitCount;
if ( nColors >256 )
nColors=0; // 如果颜色数大于256色,则没有调色板
lpvBufSrc=(LPVOID)((LPBYTE)lpbmif->bmiColors+nColors*sizeof(RGBQUAD));
int cxSrc=lpbmifh->biWidth; // 源图象宽度
int cySrc=lpbmifh->biHeight; // 源图象高度
// 计算图象每行的字节数(图象位数 x 图象宽度,如果不能被2整除则在每行后面添加一个0字节)
int nBytesPerLineSrc=((cxSrc*lpbmifh->biBitCount+31)&~31)/8; // // 目标图象信息 //
lpbmif=(LPBITMAPINFO)hDIB;
lpbmifh=(LPBITMAPINFOHEADER)lpbmif;
nColors=lpbmifh->biClrUsed ? lpbmifh->biClrUsed : 1 < <lpbmifh->biBitCount;
if ( nColors >256 )
nColors=0;
lpvBuf=(LPVOID)((LPBYTE)lpbmif->bmiColors+nColors*sizeof(RGBQUAD));
int cx=lpbmifh->biWidth;
int cy=lpbmifh->biHeight;
int nBytesPerLine=((cx*lpbmifh->biBitCount+31)&~31)/8; LPBYTE lpbPnt=NULL;
LPBYTE lpbPntSrc=NULL;
// // 通过alpha值合并两张图象的像素值 //
// 这里假设是24位真彩色图象,其他深度的图象处理方法可以以次类推
for ( int y=(cy <cySrc ? cy : cySrc); y>0 ;y-- )
{
lpbPnt=(LPBYTE)lpvBuf+nBytesPerLine*(y-1);
lpbPntSrc=(LPBYTE)lpvBufSrc+nBytesPerLineSrc*(y-1);
for ( int x=0; x <(cx <cxSrc ? cx : cxSrc); x++ )
{
for ( int i=0 ;i <3 ;i++ )
*lpbPnt++=(*lpbPnt*(255-alpha)+*(lpbPntSrc++)*alpha)/255; } } CStatic* pPic=(CStatic*)GetDlgItem(IDC_PICCOMP); ASSERT(pPic);
pPic->SetBitmap((HBITMAP)hDIB); Invalidate();
解决方案 »
- visual studio 2010 创建的MFC ActiveX 控件的工程 不能运行 提示:无法启动.ocx程序
- 大侠们帮帮忙! 如何把自己编写的进程权限提升到system或系统管理员权限??
- MFC 菜单项创建对话框,怎么给对话框里的组合框添加数据
- 关于界面调用C 函数的问题
- 请问如何等待一个线程启动?
- ============为什么纯函虚不能在构函数和析构函数中调用?============
- 请问在一个大string中,找出这个大string是否有某一个小string.有什么函数可以实现?
- cstring和ctime的转换问题!!!
- 怎样将字符型的“5”转换成数字型的 5
- 我做了一个网站,英文部分需要找兼职翻译
- VC转定义问题
- socket多用户多线程思路
我不太有时间再熟悉GDI+的环境了。
??这样强转没戏吧?
BITMAPINFO 可以自己写的
2, 自己混合两张图片的算法,这个算法其实很简单。大致过程如下:1, 定义一个混合的比例,比如1%~99%,这个值可以使用滚动条控制。
2, 做一个嵌套循环,循环计算每个像素点的值
for(int i=0; i<w1; i++)
for(int j=0; j<h1; j++)
{
pixel(i, j);
}3 像素点值的计算方法:
A图点的像素颜色值: r1, g1, b1
B图点的像素值颜色: r2, g2, b2
混合alpha的值,范围(0.01~0.99) 则最后的目标值为
r = r1 * alpha + r2 * (1 - alpha);
g = g1 * alpha + g2 * ( 1 - alpha);
b = b1 * alpha + b2 * (1 - alpha); 把最重点的颜色值就为 RGB(r, g, b)4 你使用static作为显示区域,这个地方可能不是很好,应该使用图像缓冲技术,不然你的速度会很慢。
直接创建一个 虚拟DC,把两幅图片合并后的效果画在这张图上,然后把这个虚拟图绘在你要的任何一个窗口上面即可。5 如果你使用的两张图片大小不一样,可能比较麻烦,可以考虑先做两张图片大小一样的叠加,做好了,再考虑图片大小不一样的算法。
摘自MSDNBOOL AlphaBlend(
HDC hdcDest, // handle to destination DC
int nXOriginDest, // x-coord of upper-left corner
int nYOriginDest, // y-coord of upper-left corner
int nWidthDest, // destination width
int nHeightDest, // destination height
HDC hdcSrc, // handle to source DC
int nXOriginSrc, // x-coord of upper-left corner
int nYOriginSrc, // y-coord of upper-left corner
int nWidthSrc, // source width
int nHeightSrc, // source height
BLENDFUNCTION blendFunction // alpha-blending function
);
LPBITMAPINFO lpbmif=(LPBITMAPINFO)hDIBSrc;
LPBITMAPINFOHEADER lpbmifh=(LPBITMAPINFOHEADER)lpbmif;
第二个有点道理,如果lpbmif真的是一个BITMAPINFO结构指针的话;但是第一个就不知道怎么来的了,有什么依据?另外,这种图形处理的方式,最好直接绘图而不要用控件来显示,基于你这里:
pPic->SetBitmap((HBITMAP)hDIB);
我对你这个hDIB是什么类型不清楚。
在操作时只用给内存DC上绘图,在OnDraw里面在把内存DC复制到当前DC,这样就避免了闪烁,或者试试OnEraseBkgnd()返回TRUE 。是因为窗口变大变小,移动时等等画面会重绘,以前的就没有了。要随时调用Invalidate() ,它会调用OnDraw(),同时使用双缓冲避免闪烁。