首页 > 解决方案 > 如何将图像绘制到整个矩形并且与背景无关

问题描述

我正在使用Graphics.DrawImageUnscaledAndClipped我的特定尺寸绘制图像,但它没有正确填充矩形或与背景无关。
例如,我有一个尺寸为 57x43 的图像,我想通过将其拉伸到尺寸为 240x240 的图像来填充我的图像:

示例代码:

var image = Image.FromFile(mySourceImageFile);
var bmp = new Bitmap(240, 240);
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
using (var g = Graphics.FromImage(bmp))
{
    // ... some other codes
    g.Clear(Color.Aqua); // I use this to highlight whole image
    // ... some other codes
    g.DrawImageUnscaledAndClipped(image, rect);
    // ... some other codes
}

bmp.Save(myDestinationImageFile);

我的源图像文件:
我的 57x43 Jpeg 文件

我的目标图像文件:
在此处输入图像描述

我应该补充一点,在我的目标图像文件中,底部有 5 条像素线,右侧有 4 条线,它们受背景影响,这是意料之外的!
如何在不受当前背景影响的情况下绘制图像或剪切图像来填充我的矩形?

我还应该补充一点,这是我创建目标图像的一部分,我知道我可以使用Bitmap(image, w, h).
与使用相同的结果g.DrawImage(new Bitmap(image, 240, 240), 0, 0);

标签: c#imagegraphicsimage-resizing

解决方案


我发现我可以设置CompositingMode为忽略背景CompositingMode.SourceCopy

CompositingMode.SourceCopy
指定在呈现颜色时,它会覆盖背景颜色。

所以我最好的尝试是:

var image = Image.FromFile(mySourceImageFile);
var bmp = new Bitmap(240, 240);
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
using (var g = Graphics.FromImage(bmp))
{
    g.CompositingMode = CompositingMode.SourceCopy;

    // And some other settings to improve quality
    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.SmoothingMode = SmoothingMode.HighQuality;

    g.Clear(Color.Aqua); // I use this to highlight whole image
    // ... some other codes
    g.DrawImageUnscaledAndClipped(image, rect);
    // ... some other codes
}

bmp.Save(myDestinationImageFile);

但是用这个解决方案,图像感觉的边界模糊了!!!
在此处输入图像描述

更新:
获得更好效果的一个非常糟糕的hacky方法可能是 - 不推荐 - :
使用tempBmp比原始图像更大的具有一些重复部分的图像,并在调整大小时使用它而不是原始图像,如下所示:

var image = Image.FromFile(mySourceImageFile);
var bmp = new Bitmap(240, 240);
var tempBmp = new Bitmap(image.Width + 4, image.Height + 5);

using (var g = Graphics.FromImage(tempBmp))
{
    g.DrawImage(image, 0, 0);
    g.DrawImage(image, 4, 0);
    g.DrawImage(image, 0, 5);
    g.DrawImage(image, 4, 5);
    g.DrawImage(image, 2, 0);
    g.DrawImage(image, 2, 1);        
    g.DrawImage(image, 0, 2);
    g.DrawImage(image, 1, 2);
    g.DrawImage(image, 4, 2);
    g.DrawImage(image, 3, 2);        
    g.DrawImage(image, 2, 5);
    g.DrawImage(image, 2, 4);
    g.DrawImage(image, 2, 3);
    g.DrawImage(image, 2, 2);
}

using (var g = Graphics.FromImage(bmp))
{
    // ... some other codes
    g.Clear(Color.Aqua); // I use this to highlight whole image
    // ... some other codes
    var imageRect = new Rectangle(2, 2, image.Width, image.Height);
    var drawRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    g.DrawImage(tempBmp, drawRect, imageRect, GraphicsUnit.Pixel);
    // ... some other codes
}

bmp.Save(myDestinationImageFile);

我的目标图像文件是:
我的目标图像文件

所以,我正在等待更好的解决方案;)。


推荐阅读