Изменение размера и сохранение изображения при сохранении метаданных - PullRequest
7 голосов
/ 20 августа 2010

Я пытаюсь изменить размер и сохранить изображение, что довольно просто (например, см. Этот пример внешний пример больше не действителен ).

ОднакоИспользование этого кода удаляет метаданные из изображения.Я не могу понять, как сохранить метаданные для изображения в формате JPEG.

** РЕДАКТИРОВАТЬ: Пример кода **

    public static void ResizeMethodThree(string sourceFile, string targetFile)
    {
        byte[] baSource = File.ReadAllBytes(sourceFile);

        PropertyItem[] propertyItems = new Bitmap(sourceFile).PropertyItems;

        using (Stream streamPhoto = new MemoryStream(baSource))
        {
            BitmapFrame bfPhoto = ReadBitmapFrame(streamPhoto);
            BitmapMetadata metaData = (BitmapMetadata)bfPhoto.Metadata;
            int nNewPictureSize = 200;
            int nWidth = 0;
            int nHeight = 0;

            if (bfPhoto.Width > bfPhoto.Height)
            {
                nWidth = nNewPictureSize;
                nHeight = (int)(bfPhoto.Height * nNewPictureSize / bfPhoto.Width);
            }
            else
            {
                nHeight = nNewPictureSize;
                nWidth = (int)(bfPhoto.Width * nNewPictureSize / bfPhoto.Height);
            }        

            BitmapFrame bfResize = ResizeHelper(bfPhoto, nWidth, nHeight, BitmapScalingMode.HighQuality);

            byte[] baResize = ToByteArray(bfResize);

            File.WriteAllBytes(targetFile, baResize);

            Image targetImage = new Bitmap(targetFile);
            foreach (var propertyItem in propertyItems)
            {
                targetImage.SetPropertyItem(propertyItem);
            }

            targetImage.Save(targetFile);
        }
    }

    public static BitmapFrame ResizeHelper(BitmapFrame photo, int width, 
                                           int height, BitmapScalingMode scalingMode)
    {

        var group = new DrawingGroup();
        RenderOptions.SetBitmapScalingMode(
            group, scalingMode);
        group.Children.Add(
            new ImageDrawing(photo,
                new Rect(0, 0, width, height)));
        var targetVisual = new DrawingVisual();
        var targetContext = targetVisual.RenderOpen();
        targetContext.DrawDrawing(group);
        var target = new RenderTargetBitmap(
            width, height, 96, 96, PixelFormats.Default);
        targetContext.Close();
        target.Render(targetVisual);
        var targetFrame = BitmapFrame.Create(target);
        return targetFrame;
    }

private static byte[] ToByteArray(BitmapFrame bfResize)
{
    using (MemoryStream msStream = new MemoryStream())
    {
        JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
        jpgEncoder.Frames.Add(bfResize);
        jpgEncoder.Save(msStream);
        return msStream.ToArray();
    }
}

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

Спасибо, wTs

1 Ответ

2 голосов
/ 20 августа 2010

Используйте свойство Image.PropertyItems исходного изображения, чтобы получить список элементов метаданных.Прокрутите список, вызывая Image.SetPropertyItem для целевого изображения.Обычно следует избегать изменения размера и повторного сжатия изображения в формате JPEG, поэтому лучше всего работать с несжатым оригиналом, чтобы сохранить качество и избежать артефактов.

...