0

我有一组图像,我正在按照此处System.Windows的教程使用和System.Windows.Media.Imaging(是的,不是使用 GDI+)以编程方式在它们上绘制一个简单的水印。

大多数图像不超过500Kb,但在应用简单的水印(即透明背景的文本)后,图像大小急剧增加。

例如,一张440Kb的图片在用下面的方法加水印后变成了8.33MB,这让我很震惊

private static BitmapFrame ApplyWatermark(BitmapFrame image, string waterMarkText) {
    const int x = 5;
    var y = image.Height - 20;
    var targetVisual = new DrawingVisual();
    var targetContext = targetVisual.RenderOpen();
    var brush = (SolidColorBrush)(new BrushConverter().ConvertFrom("#FFFFFF"));
    brush.Opacity = 0.5;
    targetContext.DrawImage(image, new Rect(0, 0, image.Width, image.Height));
    targetContext.DrawRectangle(brush, new Pen(), new Rect(0, y, image.Width, 20));
    targetContext.DrawText(new FormattedText(waterMarkText, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                             new Typeface("Batang"), 13, Brushes.Black), new Point(x, y));
    targetContext.Close();
    var target = new RenderTargetBitmap((int)image.Width, (int)image.Height, 96, 96, PixelFormats.Default);
    target.Render(targetVisual);
    var targetFrame = BitmapFrame.Create(target);
    return targetFrame;
}

我注意到与原始图像相比,图像质量有所提高。图像更平滑,颜色更浅。但是,你知道我真的不想要这个。我希望图像保持原样,但要包含水印。质量没有提高,当然图像尺寸也没有剧烈变化。

我在这里是否缺少任何设置来告诉我的程序保持与源图像相同的质量?如何防止我的ApplyWatermark方法更改后图像大小的显着变化?

编辑

1.这就是我转换BitmapFrameStream. 然后我用它将Stream图像保存到 AmazonS3

private Stream EncodeBitmap(BitmapFrame image) {
    BitmapEncoder enc = new BmpBitmapEncoder();
    enc.Frames.Add(BitmapFrame.Create(image));
    var memoryStream = new MemoryStream();
    enc.Save(memoryStream);
    return memoryStream;
}

2.这就是我得到的BitmapFrame方式Stream

private static BitmapFrame ReadBitmapFrame(Stream stream) {
    var photoDecoder = BitmapDecoder.Create(
        stream,
        BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.None);
    return photoDecoder.Frames[0];
}

3.这就是我从本地目录读取文件的方式

public Stream FindFileInLocalImageDir() {
    try {
        var path = @"D:\Some\Path\Image.png";
        return !File.Exists(path) ? null : File.Open(path, FileMode.Open, FileAccess.Read,  FileShare.Read);
        } catch (Exception) {
            return null;
    }
}
4

2 回答 2

1

问题是当您编辑图像时,压缩消失了。一个 730x1108 JPG 和 433kB 磁盘大小和 32 位(你提到透明度,所以 ARGB)将需要至少 730 * 1108 * 4 = 3,09MB 的磁盘。当然你可以在之后再次压缩它(对于磁盘,网络流还有什么)。

这就是为什么图像软件即使在处理压缩数据时也总是需要大量内存的原因。

结论:您将需要可用内存来处理图像。否则不可能将它完全放在手边。

于 2014-02-22T23:04:37.107 回答
0

我之前在评论中提出问题的原因是我注意到有几种不同的编码器可用。位图通常具有明显更大的文件大小,因为它存储的有关图像的信息量很大。

我自己没有测试过,但是你试过不同的编码器吗?

var pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(ApplyWatermark(null, null));

MemoryStream stm = File.Create(image);
pngEncoder.Save(stm);
return stm;
于 2014-02-23T01:17:51.377 回答