Вопрос по wpf – Самый простой способ сохранить контроль изображения wpf в файл

12

У меня есть элемент управления изображением внутри моего приложения wpf, в котором есть большое изображение, но сам элемент управления имеет размер только 60x150, это означает, что он показывает только определенную часть этого изображения. Какой самый простой способ сохранить видимую часть в файл?

Спасибо за помощь.

[РЕДАКТИРОВАТЬ] Я в конечном итоге с помощью кода, найденногоВот (которую я не смог найти до публикации здесь) ...

Grid r = new Grid();
        r.Background = new ImageBrush(image2.Source);


    System.Windows.Size sz = new System.Windows.Size(image2.Source.Width, image2.Source.Height);
    r.Measure(sz);
    r.Arrange(new Rect(sz));

    RenderTargetBitmap rtb = new RenderTargetBitmap((int)image2.Source.Width, (int)image2.Source.Height, 96d, 96d, PixelFormats.Default);
    rtb.Render(r);

    BmpBitmapEncoder encoder = new BmpBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(rtb));

    FileStream fs = File.Open(@"C:\lol.png", FileMode.Create);
    encoder.Save(fs);
    fs.Close();
Что такое image2.Source.Width? Это вместо image2.ActualWidth, просто используйте мой код. gliderkite

Ваш Ответ

2   ответа
16

RenderTargetBitmap класс иBitmapEncoder.

Определите эти методы:

void SaveToBmp(FrameworkElement visual, string fileName)
{
    var encoder = new BmpBitmapEncoder();
    SaveUsingEncoder(visual, fileName, encoder);
}

void SaveToPng(FrameworkElement visual, string fileName)
{
    var encoder = new PngBitmapEncoder();
    SaveUsingEncoder(visual, fileName, encoder);
}

// and so on for other encoders (if you want)


void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
    RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32);
    bitmap.Render(visual);
    BitmapFrame frame = BitmapFrame.Create(bitmap);
    encoder.Frames.Add(frame);

    using (var stream = File.Create(fileName))
    {
        encoder.Save(stream);
    }
}

Если у вас естьОбраз контролировать внутри контейнера, как это:

<Grid x:Name="MyGrid">
    <Image Name="MyImage" Stretch="None"></Image>
</Grid>

Вам просто нужно сделать это:

SaveToPng(MyGrid, "image.png");

В противном случае вы можете просто передать нужные размеры при использовании RenderTargetBitmap:

SaveToPng(MyImage, "image.png");

...

RenderTargetBitmap bitmap = new RenderTargetBitmap(YourWidth, YourHeight, 96, 96, PixelFormats.Pbgra32);
Когда я запускаю свой код, он работает, что вы пробовали? с & quot; MyGrid & quot; или "MyImage"?
@ Capt.Morgan, я знаю, что это старая проблема, но я столкнулся с той же проблемой, и вам нужно поместить свой обработанный элемент управления на родительский элемент управления без полей, как описано здесь:weblog.west-wind.com/posts/2007/Sep/10/…
Спасибо за это, было бы замечательно, если бы не одна маленькая проблема ... Сохраненное изображение абсолютно черного цвета ... Есть идеи, как это произошло или как это исправить? Meh
Я выполнил тестовый проект в VB.NET:here it is a sample если это может помочь; а такжеhere XAML.
@gilderkite Я полагаю, говоря "MyImage" Вы имеете в виду управление изображением в WPF, тогда да, я попробовал это Meh
3

которая возникает у других при использовании решения с глидеркитом. «Черный» изображение, по-видимому, связано с полем FrameworkElement, заставляющим его визуализироваться вне захваченного изображения. Я нашел обходной путь впрокомментируйте блог Рика Штала

В частности, измерение и расположение перед рендерингом дает возможность приспособиться к тому факту, что на картинке нет полей. Ниже приведен статический класс, который я теперь повторно использую для снимков экрана. Это основано на ответе глидеркита и информации в блоге Рика Штала.

public static class ScreenCapture
{
    public static void SaveToBmp(FrameworkElement visual, string fileName)
    {
        var encoder = new BmpBitmapEncoder();
        SaveUsingEncoder(visual, fileName, encoder);
    }

    public static void SaveToPng(FrameworkElement visual, string fileName)
    {
        var encoder = new PngBitmapEncoder();
        SaveUsingEncoder(visual, fileName, encoder);
    }

    public static void SaveToJpeg(FrameworkElement visual, string fileName)
    {
        var encoder = new JpegBitmapEncoder();
        SaveUsingEncoder(visual, fileName, encoder);
    }

    private static void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
    {
        RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32);
        Size visualSize = new Size(visual.ActualWidth, visual.ActualHeight);
        visual.Measure(visualSize);
        visual.Arrange(new Rect(visualSize));
        bitmap.Render(visual);
        BitmapFrame frame = BitmapFrame.Create(bitmap);
        encoder.Frames.Add(frame);

        using (var stream = File.Create(fileName))
        {
            encoder.Save(stream);
        }
    }
}
Я пробовал другие методы, но мои ширина и высота на визуализированном изображении всегда были слишком малы, что означало, что у меня было обрезанное содержимое в нижней и правой части изображения. Однако с помощью этого метода я получаю точные размеры, которые я ожидаю. Не знаю почему ...

Похожие вопросы