【问题标题】:GDI+ Load a jpg and save as 24bit png problemGDI+ 加载 jpg 并保存为 24bit png 问题
【发布时间】:2011-01-27 11:59:23
【问题描述】:

问题

大家好!

我有这段代码,它通过改变像素将我的 jpg 图像循环并最终将其保存为 png 类型。问题是生成的图像的位深度为 32 位。我需要它是 24 位的,任何人都可以在正确的设置方法上发光吗?我是否沿着正确的轨道将像素格式设置为 PixelFormat24bppRGB?

代码

static inline void Brighten(Gdiplus::Bitmap* img)
{
    int width = img->GetWidth()/8,height = img->GetHeight(), max = (width*height),r,g,b;
    Gdiplus::Color pixel;   
    for(int a = 0,x = 0, y = -1; a < max; ++a)
    {
        x = a%width;    
        if(x == 0)
            ++y;
        img->GetPixel(x,y,&pixel);
        r = pixel.GetR();
        g = pixel.GetG();
        b = pixel.GetB();
        if (r > 245) r = 245; 
        if (g > 245) g = 245;  
        if (b > 245) b = 245; 
        r += 10;
        g += 10;
        b += 10;
        pixel = Gdiplus::Color(r,g,b);
        img->SetPixel(x,y,pixel);;
    }
}

ULONG_PTR m_dwToken = 0;
Gdiplus::GdiplusStartupInput input;
Gdiplus::GdiplusStartupOutput output;
Gdiplus::GdiplusStartup( &m_dwToken, &input, &output );
USES_CONVERSION_EX;
Gdiplus::ImageCodecInfo* pEncoders = static_cast< Gdiplus::ImageCodecInfo* >( _ATL_SAFE_ALLOCA(1040, _ATL_SAFE_ALLOCA_DEF_THRESHOLD));
Gdiplus::DllExports::GdipGetImageEncoders(5, 1040, pEncoders );
CLSID clsidEncoder = pEncoders[4].Clsid;

Gdiplus::Bitmap img1((CT2W)L"IMG_1.JPG");
Brighten(&img1);
img1.Save((CT2W)L"IMG_1_R3.PNG",&clsidEncoder,NULL);

提前致谢!

【问题讨论】:

  • 确保额外的 8 位不是 Alpha 通道的一部分。如果它们是,那么您就可以了,只需忽略多余的位即可。尝试将额外的 8 位设置为某个值,例如 0x88,看看您的图像是否变为半透明。
  • 感谢您的快速回复,是的,我的图像确实变透明了。看起来像素正在使用额外的位。关于如何阻止它的任何想法?
  • 然后将其保留为 0。您现在拥有每通道 8 位的 ARGB/RGBA 编码图像。
  • 您还可以将 PixelFormat 作为第三个参数设置为 GdiPlus::Bitmap 构造函数为 PixelFormat24bppRGB。见:msdn.microsoft.com/en-us/library/ms536313%28VS.85%29.aspx
  • 您是说将颜色的 alpha 分量设置为 0 吗?因为这会导致图像完全透明,而不是丢弃它。我也考虑过使用位图构造函数并设置像素格式,但我不清楚如何将图像加载回来。 (还注意到我发布的代码中的一个小错误,其中 r,g,b 应设置为 += 10,我在测试是否会更改整个图像时更改了它。(不影响我的结果))我也检查并且更改 rgb 值导致它更改为 32 位,因为 gdi+ 颜色是 argb。

标签: c++ gdi+ png


【解决方案1】:

好的,我确实修复了它,我使用LockBits() 直接访问这些位并修改它们,这给了我非常需要的性能提升并将其保留为 24 位图像。

static inline void Brighten(Gdiplus::Bitmap* img)
{
    int width = img->GetWidth(),height = img->GetHeight(),r,g,b;
    Gdiplus::Rect rect(0,0,width,height);
    Gdiplus::BitmapData data;
    img->LockBits(&rect,Gdiplus::ImageLockModeWrite,PixelFormat24bppRGB,&data);
    int stride = data.Stride,offset = stride - width*3;
    byte * p1 = (byte *)(void *)data.Scan0;
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            r = p1[0];
            g = p1[1];
            b = p1[2];
            if (r > 245) r = 245; 
            if (g > 245) g = 245;  
            if (b > 245) b = 245; 
            r += 10;
            g += 10;
            b += 10;    
            p1[0] = r;
            p1[1] = g;
            p1[2] = b;
            p1 += 3;
        }
        p1 += offset;
    }
    img->UnlockBits(&data);     
}

感谢您的所有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 2013-05-10
    • 2011-10-28
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多