应用简单水印后,图像大小急剧增加

时间:2014-02-22 21:52:25

标签: c# wpf windows image wic

我有一组图像,我按照here中的教程,使用System.WindowsSystem.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。这是我将BitmapFrame转换为Stream的方法。然后我使用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;
    }
}

2 个答案:

答案 0 :(得分:1)

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

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

结论:您将需要可用内存来处理图像。不可能完全掌握它。

答案 1 :(得分:0)

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

我自己没有对此进行过测试,但您尝试过不同的编码器吗?

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

MemoryStream stm = File.Create(image);
pngEncoder.Save(stm);
return stm;