2012-05-06 2 views
11

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

Благодарим за помощь.

[EDIT] Я закончил с использованием кода найден here (который я не смог найти, прежде чем разместить здесь) ...

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(); 
+0

Что такое image2.Source.Width? Вместо этого вместо этого используется image2.ActualWidth, просто используйте мой код. – gliderkite

ответ

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); 
    } 
} 

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

<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); 
+4

Спасибо за это, это было бы фантастически, если бы не одна небольшая проблема .. Сохраненное изображение является черным цветом ... Любые идеи, как это произошло или как это исправить? – Meh

+0

Когда я запускаю свой код, он работает, что вы пробовали? с «MyGrid» или «MyImage»? – gliderkite

+0

Я сделал тестовый проект в VB.NET: [здесь это образец] (http://ideone.com/wZH72), если он может помочь; и [здесь] (http://ideone.com/CJrJA) XAML. – gliderkite

2

Я столкнулся с тем же «черным» изображением, что другие делали при использовании решения gliderkite. «Черное» изображение, похоже, связано с маркой FrameworkElement, заставляя его визуализироваться вне захваченного изображения. Я нашел обходное решение в comment on Rick Stahl's blog

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

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); 
     } 
    } 
} 
Смежные вопросы