PNG转BMP如何去除alpha透明层 200分求解

DrSmart 2010-11-12 09:38:29
1. 要求是VC和XP下要求将PNG转化为BMP,同时不能有阴影,就是如何去除PNG中的透明层,关键是PNG的透明可能分级,比如0-255,不是纯色。

使用CImage类的Detach方法转的HBitmap中,原有的阴影会有明显的黑色,但是PNG的alpha通道是0-255,还不是纯黑,所以仅仅滤色还不行。有啥好的方法没有,在处理PNG时就去除透明层,目前可以选择的有

GDI+,但是不知道具体的处理方法,以及GDI+中的类如何转回BITMAP对象。
LibPng不知道可以解决问题不,没有用过。
CxImage不能考虑,据说质量不好,这个库感觉不太放心。
必须VC6解决,据说VC2008支持PNG,目前使用了VC6版的CImage。
微软的IPicture配合OleLoadPicture不支持PNG,郁闷了,哪位大牛帮下忙,分不够了,再加

...全文
1265 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
DrSmart 2010-11-14
  • 打赏
  • 举报
回复
png的透明不知道是专门一层,还是差值运算的,不过,我发现libpng可以显示透明的,画到hdc上,那么如何将hdc上的内容转成hbitmap呢
laviewpbt 2010-11-14
  • 打赏
  • 举报
回复
楼主,你删除了一个alpha通道,又要保留边缘的一些渐变,是不可能的。
lambochan 2010-11-14
  • 打赏
  • 举报
回复
全是先和背景作alpha混合再把结果帖出来的.如果去掉那层alpha的话,都是那副死相..

最直接的做法就是把CxImage处理png的那部分cut出来,想怎搞就可以怎搞了.
xhjbeidoulong 2010-11-13
  • 打赏
  • 举报
回复
这个用GDI+就可以,2楼的代码就是。

不过png有透明通道的话,图片底层会是黑色, 如果你要想背影是其它颜色, 那就创建Graphics,在上面先填充背景, 再将png绘上, 然后再将Graphics中的图保存为bmp
DrSmart 2010-11-13
  • 打赏
  • 举报
回复
先给大家说下,最重要的问题是,png转bmp有难看的阴影,因为png的alpha可能是0-255,转成bmp后可能背景不是单色,我的问题是如何去除png中的透明层,然后转成bmp。看了下GDI+下的Bitmap类是有一个GetHBitmap方法最终从HBitmap句柄转成GDI的BITMAP对象。
zgl7903 2010-11-13
  • 打赏
  • 举报
回复
用VS2008 CImage类比较容易,可以用VS2008做一个动态库,让VC6调用
其实也是通过封装GDI+实现的,


#include "AltImage.h"
BOOL ConvPngToBMP(LPCTSTR szPNG, LPCTSTR szDst, COLORREF bkColor=RGB(255,255,255))
{
CImage Image;
if(Image.Load( szPNG ) == S_OK)
{
CDC *pRefDC = CDC::FromHandle(GetDC(NULL));

int cx=Image.GetWidth();
int cy=Image.GetHeight();

CDC memDC;
memDC.CreateCompatibleDC(pRefDC);
CBitmap mBitmap;
mBitmap.CreateCompatibleBitmap(pRefDC, cx, cy);
CBitmap *pOldBitmap = memDC.SelectObject(&mBitmap);
memDC.FillSolidRect(0,0,cx,cy,bkColor);//

Image.AlphaBlend(memDC.GetSafeHdc(), 0, 0);

memDC.SelectObject(pOldBitmap);
memDC.DeleteDC();
DeleteDC(pRefDC->GetSafeHdc());

Image.Destroy();
Image.Attach((HBITMAP)mBitmap);
Image.Save(szDst);

mBitmap.DeleteObject();

return TRUE;
}

return FALSE;
}

zhaozidong86 2010-11-13
  • 打赏
  • 举报
回复
晕,我想用IconWorkShop把背景弄成透明的,它出来个白的
DrSmart 2010-11-13
  • 打赏
  • 举报
回复
楼上的,你搞笑呢,这样背景变成白色的,那原来的透明层变成杂色了,看起来更明显了。dc能处理这个,就不来问了
hastings 2010-11-13
  • 打赏
  • 举报
回复
画到内存DC上,画之前,FillRect为白色先~~这样底色就不是黑色了~~
然后把内存DC保存为BMP~~
傻X 2010-11-12
  • 打赏
  • 举报
回复
楼主瞅瞅这个,老贴的代码。


#include "gdiplus.h"
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")

INT GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders

UINT size = 0; // size of the image encoder array in bytes

ImageCodecInfo* pImageCodecInfo = NULL;

GetImageEncodersSize(&num, &size);

if(size == 0)
{
return -1; // Failure
}

pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
{
return -1; // Failure
}
GetImageEncoders(num, size, pImageCodecInfo);

for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}

void Png2Bmp( const LPCWSTR lpczPNGFilePath, LPCWSTR lpBmpPath)
{

CLSID encoderClsid;
Status stat;
Image* image = NULL;
image = Bitmap::FromFile( lpczPNGFilePath, TRUE);
GetEncoderClsid(L"image/bmp", &encoderClsid);
stat = image->Save( lpBmpPath, &encoderClsid, NULL);
delete image;
}


xuzhx 2010-11-12
  • 打赏
  • 举报
回复
GDI+ 中Image类有个Save,你研究一下就行了, 就两行代码:

Image* image = new Image(L"1.png");
image.Save(****);

// Save 里的参数可以指定格式

转回也很简单, 你可以找到Bitmap 的一个成员, 名字忘了就是 HBITMAP

其实,没必要网上问的, 你仔细研究一下 类的成员函数就可以了

19,468

社区成员

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

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