C语言 如何将24位BMP图片转换为带有alpha通道的32位BMP

love_basketball 2011-11-24 05:49:51
我已经可以取到24位BMP的像素信息,不知道怎么添加alpha通道。请高手指教!
...全文
780 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
love_basketball 2012-01-05
  • 打赏
  • 举报
回复
OK 做出来了。我在添加Alpha通道的时候没有对RGB值进行合成,以为不需要,通过公式合成之后就有效果了合成公式是:
显示颜色 = 源像素颜色 X alpha / 255 + 背景颜色 X (255 - alpha) / 255
结贴
风来我也来 2012-01-05
  • 打赏
  • 举报
回复
你显示的函数支持四通道图像中存在阿尔法通道指示为透明度么?
如果不支持你也看不到效果。
love_basketball 2012-01-04
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wangguanguo 的回复:]
遍历像素:

C/C++ code


char* pvImage;//保存图像数据的一块区域
//因为转换后的destbmp图像是4通道的,而srcImg是3通道的,所以应该给destbmp多分配4/3
pvImage = (char*)malloc(srcImg->height*srcImg->widthStep*4/3+3);
int i=0;……
[/Quote]
谢谢 明白是为什么那么写了,但是我导出来的图片没有透明效果,图片确实是32位的。alpha的值我设置成0或者255都是一个效果。
love_basketball 2012-01-04
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wangguanguo 的回复:]
遍历像素:

C/C++ code


char* pvImage;//保存图像数据的一块区域
//因为转换后的destbmp图像是4通道的,而srcImg是3通道的,所以应该给destbmp多分配4/3
pvImage = (char*)malloc(srcImg->height*srcImg->widthStep*4/3+3);
int i=0;……
[/Quote]

那个imageData是图像的像素信息吧,pvImage[i]=srcImg->imageData[a*srcImg->widthStep+3*b];//b分量
这句是把把24位的像素信息复制给32位的,我不太明白为什么要这么复制,而不能用srcImg->imageData[i]
linfeng_hebut 2012-01-03
  • 打赏
  • 举报
回复
不知道楼主的问题是怎么解决的?请教
wangguanguo 2012-01-03
  • 打赏
  • 举报
回复
遍历像素:

char* pvImage;//保存图像数据的一块区域
//因为转换后的destbmp图像是4通道的,而srcImg是3通道的,所以应该给destbmp多分配4/3
pvImage = (char*)malloc(srcImg->height*srcImg->widthStep*4/3+3);
int i=0;
for(int a=0;a<srcImg->height;a++)
{
for(int b=0;b<srcImg->width;b++)
{
pvImage[i]=srcImg->imageData[a*srcImg->widthStep+3*b];//b分量
pvImage[i+1]=srcImg->imageData[a*srcImg->widthStep+3*b+1];//g分量
pvImage[i+2]=srcImg->imageData[a*srcImg->widthStep+3*b+2];//r分量
pvImage[i+3]=0;//alpha通道置零
i+=4;
}

这段代码的srcImg->height,srcImg->widhtStep,srcImg->imageData用的是opencv的格式,MFC中有对应的格式,自己修改一下。不知道这是不是你想要的。
leechrockgames 2012-01-03
  • 打赏
  • 举报
回复
[C/C++]
VOID ENobject2D::LHxxDRAW_2DIMAGE(char *Tname,void* value,int distance,int veversal)
{
int i=0;
TList=ENobject2DListOb.GetNode(Tname);
LHxx2DIMAGE *ob=TList->ObjectData;
if(ob->LHxxVisible<=0){return;}
LHxxMOVE_2DIMAGE(Tname,ob->LHxxIx,ob->LHxxIy,ob->LHxxMirrorXOff,ob->LHxxMirrorYOff);
//设置数字显示
if(distance!=-8888)
{
char ss[200];
strcpy(ss,(char*)value);
int size=strlen(ss);
int tempx=ob->LHxxIx;
int tempy=ob->LHxxIy;
for(i=0;i<size;i++)
{
ob->LHxx2DATCurFrame=(int)ss[i]-48;//计得ASKII码
if(veversal==0)//正常X
{
ob->LHxxIx=tempx+(ob->LHxxIw*i/2+(distance*i));
ob->LHxxIy=tempy;
}
else if(veversal==1)//反转X
{
ob->LHxxIx=tempx+(ob->LHxxIw*((size-1)-i)/2+distance*((size-1)-i));
ob->LHxxIy=tempy;
}
else if(veversal==2)//正常Y
{
ob->LHxxIy=tempy+(ob->LHxxIh*((size-1)-i)/2+distance*((size-1)-i));
}
else if(veversal==3)//反转Y
{
ob->LHxxIy=tempy+(ob->LHxxIh*i/2+(distance*i));
}
LHxxMOVE_2DIMAGE(Tname,ob->LHxxIx,ob->LHxxIy,ob->LHxxMirrorXOff,ob->LHxxMirrorYOff);
ob->LHxxIx=tempx;
ob->LHxxIy=tempy;
this->ENobject::m_pd3dDevice->SetTexture( 0, ob->LHxx2DTexAT[ob->LHxx2DATCurFrame].LHxxATTexture );
//设置渲染模式flat/gouraud
TENd3dOb->ENrenderStateOb->RenderState_RenderMode(2);
//设置渲染模式(渲染出正常面或者不断渲染出最底的面)(2D镜像要打开这个)
TENd3dOb->ENrenderStateOb->RenderState_CULLMODE(D3DRS_CULLMODE,D3DCULL_NONE);
//2D禁用,不然显示次序相反
//深度测试
//1:激活深度缓冲区;
//2:设置深度缓冲区;
//3:允许深度缓冲区更新
//4:设置深度测试
TENd3dOb->ENrenderStateOb->RenderState_ZFUNCTEST(false);
//辅助功能
//1:使程序允许抖动
TENd3dOb->ENrenderStateOb->RenderState_ASSISTANT(true);
//纹理alpha混合/alpha测试
TENd3dOb->ENrenderStateOb->RenderState_ALPHATEXTRUE(true);
//1:物理RGB混合方式
//2:设置纹理坐标是第几个纹理层(默认纹理坐标)P197
//3:设置纹理坐标输出为几维(2D)P199
TENd3dOb->ENrenderStateOb->RenderState_TEXTURE_BasicSet(0,1);
//纹理采样
TENd3dOb->ENrenderStateOb->RenderState_TEXTURE_Sampling(0,ob->Texture2DSample,1);
//纹理寻址
TENd3dOb->ENrenderStateOb->RenderState_TEXTURE_VisMode(0,ob->Texture2DAddress,ob->Texture2DAddressColor,1);
this->ENobject::m_pd3dDevice->SetStreamSource( 0, ob->LHxx2DMVertexBuffer, 0, sizeof(LHxx2DSCREENVERTEX) );
this->ENobject::m_pd3dDevice->SetFVF( LHxx2DSCREENVERTEXFVF );
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);
//基本图元:将顶点连结成基本图元
//能够绘制当前的索引数组;P56(多边形用)
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 2*3);//顶点集合
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0,3*2 );//线段集合
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_LINESTRIP, 0,3*2);//不间断线段集合
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0,2);//三角形集合
this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0,2);//不间断三角形集合
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0,2);//fan集合
}
}
else if(distance==-8888)//正常图片显示
{

this->ENobject::m_pd3dDevice->SetTexture( 0, ob->LHxx2DTexAT[ob->LHxx2DATCurFrame].LHxxATTexture );
//设置渲染模式flat/gouraud
TENd3dOb->ENrenderStateOb->RenderState_RenderMode(3);
//设置渲染模式(渲染出正常面或者不断渲染出最底的面)(2D镜像要打开这个)
TENd3dOb->ENrenderStateOb->RenderState_CULLMODE(D3DRS_CULLMODE,D3DCULL_NONE);
//2D禁用,不然显示次序相反
//深度测试
//1:激活深度缓冲区;
//2:设置深度缓冲区;
//3:允许深度缓冲区更新
//4:设置深度测试
TENd3dOb->ENrenderStateOb->RenderState_ZFUNCTEST(false);
//辅助功能
//1:使程序允许抖动
TENd3dOb->ENrenderStateOb->RenderState_ASSISTANT(true);
//纹理alpha混合/alpha测试
TENd3dOb->ENrenderStateOb->RenderState_ALPHATEXTRUE(true);
//1:物理RGB混合方式
//2:设置纹理坐标是第几个纹理层(默认纹理坐标)P197
//3:设置纹理坐标输出为几维(2D)P199
TENd3dOb->ENrenderStateOb->RenderState_TEXTURE_BasicSet(0,1);
//纹理采样
TENd3dOb->ENrenderStateOb->RenderState_TEXTURE_Sampling(0,ob->Texture2DSample,1);
//纹理寻址
TENd3dOb->ENrenderStateOb->RenderState_TEXTURE_VisMode(0,ob->Texture2DAddress,ob->Texture2DAddressColor,1);
this->ENobject::m_pd3dDevice->SetStreamSource( 0, ob->LHxx2DMVertexBuffer, 0, sizeof(LHxx2DSCREENVERTEX) );
this->ENobject::m_pd3dDevice->SetFVF( LHxx2DSCREENVERTEXFVF );
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);
//基本图元:将顶点连结成基本图元
//能够绘制当前的索引数组;P56(多边形用)
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 2*3);//顶点集合
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0,3*2 );//线段集合
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_LINESTRIP, 0,3*2);//不间断线段集合
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0,2);//三角形集合
this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0,2);//不间断三角形集合
// this->ENobject::m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0,2);//fan集合

}
//还原
TENd3dOb->ENrenderStateOb->RenderState_Reset();

//--采样还原--
//线性采样
// m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
// m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );

//多级渐进采样
// m_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
//第三个参数:值越大锯齿越多,负数就变模糊
// m_pd3dDevice->SetSamplerState(0, D3DSAMP_MAXMIPLEVEL,-1);//Test1:level
//--采样还原--


for(i=0;i<8;i++)
{
m_pd3dDevice->SetTextureStageState( i,D3DTSS_COLOROP,D3DTOP_DISABLE);
}

}



#include"ENrenderState.h"
//设置填充点/线/面
void ENrenderState::RenderState_FillMode(int Off)
{
if(Off==1)
{
m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_POINT );//
}
else if(Off==2)
{
m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
}
else if(Off==3)
{
m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
}
}
//设置渲染模式flat/gouraud
void ENrenderState::RenderState_RenderMode(int Off)
{
if(Off==1)
{
m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
}
else if(Off==2)
{
m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
}
else if(Off==3)
{
m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_PHONG );
}
}
//desc:设置雾化
//parametar - type : 类型
// color: 雾色
// start: 设置起始位置(第一类)
// end : 设置结束位置(第一类)
// density: 密度(第一类除外)
VOID ENrenderState::RenderState_SetFog(int type,COLORREF color,float start,float end,
float density,bool use)
{
if(use==false) {return;}
// m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
//激活雾化处理
m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,TRUE );
//设置fog color(alpha不起作用);P178
m_pd3dDevice->SetRenderState( D3DRS_FOGCOLOR,color);//0x00ffffFF
//检测硬件是否支持log发散处理;p180
D3DCAPS9 stCaps;
m_pd3dDevice->GetDeviceCaps (&stCaps);
if (stCaps.RasterCaps&D3DPRASTERCAPS_FOGRANGE)
{
//开启发散处理
m_pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, true);
}
switch(type)
{
//线性log
case 0:
{
m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE , D3DFOG_LINEAR);
m_pd3dDevice->SetRenderState( D3DRS_FOGSTART , *(DWORD*)&start);
m_pd3dDevice->SetRenderState( D3DRS_FOGEND , *(DWORD*)&end);
break;
}
case 1://指数log
{
m_pd3dDevice->SetRenderState( D3DRS_FOGDENSITY , *(DWORD*)&density);
m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE , D3DFOG_EXP);
break;
}
case 2://2次指数log
{
m_pd3dDevice->SetRenderState( D3DRS_FOGDENSITY , *(DWORD*)&density);
m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE , D3DFOG_EXP2);
break;
}
default:
{
MessageBox(hWnd,"fog type is wrong","type error",MB_OK);
}
}
}
//还原
void ENrenderState::RenderState_Reset()
{
//恢复总是通过深度测试
// m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS );//设置深度测试
//是否用深度测试(是否按物体在空间的坐标,设置渲染顺序)
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, true );
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );//不激活ALPHA混合计算(用于绘制半透明)P159
m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );//该函数用于用户设置渲染状态:参数1 设置渲染状态 参数2 状态值,本句使透明度混合可用
//激活雾化处理
m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,FALSE);
//纹理alpha混合/alpha测试
RenderState_ALPHATEXTRUE(false);
//辅助功能
//1:使程序允许抖动
RenderState_ASSISTANT(false);
//深度测试
//1:激活深度缓冲区;
//2:设置深度缓冲区;
//3:允许深度缓冲区更新
//4:设置深度测试
RenderState_ZFUNCTEST(true);
}
[/code]

主要是看你渲染状态,设置ALPHA
azand 2011-11-28
  • 打赏
  • 举报
回复
位图有图像信息头,这个图像信息头描述的就是位图的像素深度、长、宽等信息。图像信息头改成32位的,然后写图像像素数据的时候每个像素用4个字节表示,第一个(或者是最后一个)字节就是透明度的值。这个MSDN上有,你搜BITMAPINFOHEADER就知道了。
fengbingchun 2011-11-25
  • 打赏
  • 举报
回复
opencv的cvCvtColor函数可以
love_basketball 2011-11-24
  • 打赏
  • 举报
回复
这个我也知道要这么做,但是不知道怎么实现,我现在可以得到所有RGB的值,不知道怎么来添加那个alpha。你说的扩展成三十二位的是是不是把信息头的biBitCount改成32,然后再用每行的像素数乘以4,来给每个像素增加一个alpha的值?
relaxisland 2011-11-24
  • 打赏
  • 举报
回复
把每个像素24位扩展成32位,应该就可以了。
根据所需要的透明度,把第四个八位设置成0x00到0xff之间。

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧