Gdiplus的坑:通过DrawImage进行放大不是很靠谱

由于DrawImage指定destRect和srcRect绘制后,会自动把原图放大到destRect的大小,实现了放大效果,这是很通常的做法;

但如果要求放大得很精确的时候,比如需要将原图放大到destRect后再平铺到整个窗口,这里面其实有个很严重的问题;

比如运行一下如下代码:

            if (g_pSrcImage != NULL)
            {
                Graphics graphics(hDC);
                Rect zoomRect(0, 0, g_pSrcImage->GetWidth() * 7, g_pSrcImage->GetHeight() * 7);
                Bitmap* pImageScale = new Bitmap(zoomRect.Width, zoomRect.Height);
                if (pImageScale != NULL)
                {
                    Graphics graphicsScale(pImageScale);
                    graphicsScale.Clear(Color(0, 255, 0)); //填充绿色
                    graphicsScale.DrawImage(g_pSrcImage, zoomRect, 0, 0, g_pSrcImage->GetWidth(), g_pSrcImage->GetHeight(), UnitPixel);

                    graphics.DrawImage(pImageScale, 0, 0, zoomRect.X, zoomRect.Y, zoomRect.Width, zoomRect.Height, UnitPixel);
                    delete pImageScale;
                    pImageScale = NULL;
                }
            }
这是一个典型的通过DrawImage等比放大的代码,但实际结果是zoomRect并没有被充满,右边和下边都多出了几个像素预填充的绿色;

再拿这张放大后的图去平铺那就大悲剧了,好多绿色分割线……


解决办法是先使用ScaleTransform设置放大比例,再用FillRectangle把原图填充到zoomRect,代码如下:

            if (g_pSrcImage != NULL)
            {
                Graphics graphics(hDC);
                Rect zoomRect(0, 0, g_pSrcImage->GetWidth() * 7, g_pSrcImage->GetHeight() * 7);
                Bitmap* pImageScale = new Bitmap(zoomRect.Width, zoomRect.Height);
                if (pImageScale != NULL)
                {
                    Graphics graphicsScale(pImageScale);
                    graphicsScale.Clear(Color(0, 255, 0)); //填充绿色
                    // 方法一:正确方法
                    TextureBrush brush(g_pSrcImage);
                    graphicsScale.ScaleTransform((REAL)((REAL)zoomRect.Width / (REAL)g_pSrcImage->GetWidth()),
                        (REAL)((REAL)zoomRect.Height / (REAL)g_pSrcImage->GetHeight()));
                    graphicsScale.FillRectangle(&brush, zoomRect);

                    // 方法二:右边和下边会有几个像素预填充的绿色
                    //graphicsScale.DrawImage(g_pSrcImage, zoomRect, 0, 0, g_pSrcImage->GetWidth(), g_pSrcImage->GetHeight(), UnitPixel);

                    graphics.DrawImage(pImageScale, 0, 0, zoomRect.X, zoomRect.Y, zoomRect.Width, zoomRect.Height, UnitPixel);
                    delete pImageScale;
                    pImageScale = NULL;
                }
            }



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`Gdiplus::Bitmap::FromStream` 是 GDI+ 库中的一个函数,用于从流中加载图像。其函数原型如下: ```c++ Gdiplus::Status FromStream( IStream *stream, BOOL useEmbeddedColorManagement = FALSE ); ``` 其中,`stream` 参数是一个指向 `IStream` 接口的指针,用于指定要加载的流对象;`useEmbeddedColorManagement` 参数是一个布尔值,用于指定是否使用嵌入的颜色管理数据。 `Gdiplus::Bitmap::FromStream` 函数返回一个 `Gdiplus::Status` 枚举值,表示加载图像的结果。如果加载成功,返回值为 `Gdiplus::Ok`,否则返回其他错误代码。 使用示例: ```c++ Gdiplus::Bitmap* bmp = NULL; // 图像对象指针 IStream* istream = NULL; // 流对象指针 // 创建流对象 CreateStreamOnHGlobal(NULL, TRUE, &istream); // 将数据写入流 // ... // 从流中加载图像 Gdiplus::Status status = Gdiplus::Bitmap::FromStream(istream, &bmp); // 检查是否成功加载图像 if (status != Gdiplus::Ok || bmp == NULL) { // 加载失败,处理错误 // ... } // 成功加载图像,可以使用 bmp 对象进行绘制等操作 // ... // 释放资源 delete bmp; istream->Release(); ``` 在使用 `Gdiplus::Bitmap::FromStream` 函数加载图像时,需要注意以下几点: - 流对象必须在使用完毕后释放,否则会造成内存泄漏; - 图像对象也必须在使用完毕后释放; - 加载图像时需要检查返回值和图像对象是否为空,避免出现错误。 希望这可以帮助到你。如果你有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值