2013-04-03 5 views
5

Ich habe ein Bild und ich möchte es neu Größe und muss in meinem Temp-Ordner speichern.Bild in WPF ändern

, was ich versucht habe, ist wie folgt:

UIElement uie = CanvasHost.Child; 
int width = 800; 
int height = (int)((width/(double)((FrameworkElement)uie).Width) * (int)((FrameworkElement)uie).Height);   
RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); 
rtb.Render(uie); 

string dir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\temp\"; 
if (!Directory.Exists(dir)) 
     Directory.CreateDirectory(dir); 

long size = 0; 

string filePath = dir + DateTime.Now.Ticks.ToString() + (isPng ? ".png" : ".jpg"); 
BitmapEncoder enc = null; 

using (FileStream fs = File.Create(filePath)) 
{ 
    if (isPng) 
     enc = new PngBitmapEncoder(); 
    else 
     enc = new JpegBitmapEncoder(); 

    enc.Frames.Add(BitmapFrame.Create(rtb)); 
    enc.Save(fs); 

    size = fs.Length; 
} 

aber wenn ich Bild wie dieses schaffen speichert sie Teil des Bildes in temporären Ordner. (Wie im obigen Bild gezeigt)

enter image description here

wie kann ich Größe volles Bild wieder? was ich hier verpasst habe?

EDIT: Wie in der obigen Antwort erwähnt von Erti-Chris Eelmaa habe ich den Code wie folgt geändert. und es funktioniert ......

UIElement uie = CanvasHost.Child; 
int width = DataCache.Instance.CurrentProject.MaxPhotoEdgeSize; 
int height = (int)((width/(double)((FrameworkElement)uie).Width) * (int)((FrameworkElement)uie).Height); 

RenderTargetBitmap rtb = new RenderTargetBitmap((int)((FrameworkElement)uie).Width, (int)((FrameworkElement)uie).Height, 96, 96, PixelFormats.Pbgra32); 
rtb.Render(uie); 

ImageSource im = (ImageSource)rtb.Clone(); 
BitmapFrame bp = CreateResizedImage(im, width, height, 1); //method suggested by Erti-Chris Eelmaa 
string dir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\temp\"; 

if (!Directory.Exists(dir)) 
    Directory.CreateDirectory(dir); 

long size = 0; 

string filePath = dir + DateTime.Now.Ticks.ToString() + (isPng ? ".png" : ".jpg"); 
BitmapEncoder enc = null; 

using (FileStream fs = File.Create(filePath)) 
{ 
    if (isPng) 
     enc = new PngBitmapEncoder(); 
    else 
     enc = new JpegBitmapEncoder(); 


    enc.Frames.Add(BitmapFrame.Create(bp)); 
    enc.Save(fs); 

    size = fs.Length; 
} 
+0

Sie müssen nach der Erstellung Höhe und Breite des Bitmap ändern. Was Sie hier tun, ist, dass Sie ein neues Bitmap kleiner Größe erstellen und es mit Originalbild ohne Größenänderung füllen. Sie erstellen ein Bitmap der Originalgröße und verwenden dann seine Höhe und Breite, um seine Größe zu ändern. –

+0

@FaisalHafeez können Sie mehr darüber erklären? Wie kann ich es Größe – DevT

+0

Hier machen Sie ein Bitmap der Breite und Höhe Größe. Jetzt ist das von reduzierter Größe. Aber wenn Sie es mit Bild füllen, wird es nur einen Teil des Bildes kopieren (das passiert in Ihrem Fall). Sie müssen eine andere Funktion verwenden, um dies zu implementieren. –

Antwort

14

Genau diese Methode verwenden Bitmapframe zu erhalten, nach, dass Sie es einfach sparen können auf HDD PngBitmapEncoder verwenden.

private static BitmapFrame CreateResizedImage(ImageSource source, int width, int height, int margin) 
{ 
    var rect = new Rect(margin, margin, width - margin * 2, height - margin * 2); 

    var group = new DrawingGroup(); 
    RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality); 
    group.Children.Add(new ImageDrawing(source, rect)); 

    var drawingVisual = new DrawingVisual(); 
    using (var drawingContext = drawingVisual.RenderOpen()) 
     drawingContext.DrawDrawing(group); 

    var resizedImage = new RenderTargetBitmap(
     width, height,   // Resized dimensions 
     96, 96,    // Default DPI values 
     PixelFormats.Default); // Default pixel format 
    resizedImage.Render(drawingVisual); 

    return BitmapFrame.Create(resizedImage); 
} 
+0

Ich habe diese Funktion verwendet und Sie meinen anstelle von 'RenderTargetBitmap'' 'PngBitmapEncoder' r8? Wenn ja, wie kann ich 'enc.Frames.Add (BitmapFrame.Create (rtb));} speichern, weil hier ein visuelles Objekt benötigt wird. – DevT

+0

Ich habe meine Frage bearbeitet. Wenn ich so speichere, speichert es schwarzes Bild. Warum das? – DevT

+0

in der Lage, das Problem zu lösen. Vielen Dank.... – DevT

14

In Bezug auf den selbst Ändern der Größe, WPF mit TransformedBitmap scheint ein wenig einfacher:

var bitmap = new TransformedBitmap(bitmapSource, 
    new ScaleTransform(
     newWidth/bitmapSource.PixelWidth, 
     newHeight/bitmapSource.PixelHeight));