У меня есть набор изображений, на которые я программно рисую простой водяной знак, используя System.Windows
и System.Windows.Media.Imaging
(да, не с помощью GDI+), следуя инструкциям в здесь.
Размер большинства изображений не превышает 500Кб, но после применения простого водяного знака, представляющего собой текст с прозрачным фоном, размер изображения резко увеличивается.
Например, изображение размером 440 КБ становится 8,33 МБ после применения водяного знака описанным ниже способом, и это меня шокирует.
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;
}
}
BitmapFrame
вStream
, а затем я сохраняю поток в Amazon, используя API AmazonS3 для .net. - person user3332579   schedule 23.02.2014BitmapFrame
вStream
? я должен также опубликовать этот код? - person user3332579   schedule 23.02.2014PngBitmapEncoder
, так как формат выходного изображения —png
. однако недавно я заметил, что размер изображения меняется после применения водяного знака. например, изображение960x1280
становится1280x1706
при применении водяного знака, хотя я указываю установить ширину и высоту целевого кадра такими же, как размеры исходного изображения. может быть, это причина того, почему размер изображения становится больше? как сохранить исходный размер? что мне не хватает? пожалуйста помоги. - person user3332579   schedule 23.02.2014