WPF - черный фон вокруг сохраненного холста в формате jpeg

У меня возникли трудности с JpegBitmapEncoder, поскольку он создает изображение, помещенное в черный прямоугольник. и у меня нет решения для исправления.

 private void SaveImage(Canvas canvas, string fileName)
    {
        SaveFileDialog s = new SaveFileDialog();
        s.FileName = "Pic";
        s.DefaultExt = ".jpg";
        s.Filter = "JPG files (.jpg)|*.jpg";

        Nullable<bool> result = s.ShowDialog();
        if (result == true)
        {
            RenderTargetBitmap renderBitmap = new RenderTargetBitmap(6646, 3940, 2000d, 2000d, PixelFormats.Pbgra32);

            canvas.Measure(new Size((int)canvas.Width, (int)canvas.Height));
            canvas.Arrange(new Rect(new Size((int)canvas.Width, (int)canvas.Height)));

            renderBitmap.Render(canvas);

            string filename = s.FileName;
            JpegBitmapEncoder encoder = new JpegBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(renderBitmap));

            using (FileStream file = File.Create(filename))
            {
                encoder.Save(file);
            }
        }
    }

с этим кодом я получаю:

введите здесь описание изображения

но когда я использую PngBitmap Encoder, этого не происходит. Кто-нибудь может пролить свет? Как удалить черный прямоугольник или, возможно, заполнить его, увеличив размеры изображения?


person MicroDev92    schedule 12.01.2017    source источник


Ответы (1)


.png поддерживает прозрачность, а .jpg — нет. Я подозреваю, что фон вашего холста прозрачен, и, поскольку он не знает, что с ним делать, он просто оставляет пиксели по умолчанию (0,0,0), то есть черный. По умолчанию Png имеет значение (0,0,0,0), что означает прозрачный черный цвет.

Или ваш холст не имеет тех же размеров, что и изображение (вы создаете свое изображение с жестко заданной шириной и высотой, а не используете ширину и высоту вашего холста). Поскольку он больше, он отображает только те части, которые на самом деле покрывает холст.

Если это первый случай, попробуйте установить фон холста = «Белый» на свой холст, чтобы он отображал все это без прозрачности. Если это второе, попробуйте создать Rectangle размеры вашего изображения с соответствующим Fill="White" и отрисовать его первым перед вашим холстом. Что-то вроде этого:

Rectangle fillBackground = new Rectangle {
    Width = 6646,
    Height = 3940,
    Fill=Brushes.White
}

renderBitmap.Render(fillBackground);
renderBitmap.Render(canvas);

Небольшой совет: на самом деле вам не следует использовать ширину и высоту, это может быть NAN для элемента управления, макет которого определяется его родителем. На самом деле вы должны использовать Canvas.ActualWidth и Canvas.ActualHeight или Canvas.RenderSize.Width/Height. На самом деле это будет постоянно отражать размер экрана.

Кроме того, чтобы рассчитать размер выходного изображения с учетом вашего выбора DPI, вы можете использовать следующее:

RenderTargetBitmap renderBitmap = new RenderTargetBitmap(Width * DPI/96, 
                                                         Height * DPI/96, 
                                                         DPI, DPI, PixelFormats.Pbgra32);
person Joe    schedule 12.01.2017
comment
Это на самом деле хорошо, и это решает проблему, проблема заключалась в том, что у меня была рамка (о которой я забыл) вокруг холста (холст на самом деле имеет размер изображения xD), поэтому, когда я заполняю границу белым цветом, это на самом деле делает трюк! Tnx много! - person MicroDev92; 13.01.2017
comment
Нет проблем, я боролся с экспортом изображений/скриншотов всю неделю и случайно столкнулся с этой проблемой! - person Joe; 13.01.2017