2013-04-03 40 views
5

tôi có một hình ảnh và tôi muốn kích thước lại nó và cần phải lưu trong thư mục tạm thời của tôi.Thay đổi kích thước hình ảnh trong WPF

những gì tôi đã cố gắng như sau:

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

nhưng khi tôi tạo ra hình ảnh như thế này nó tiết kiệm một phần của hình ảnh trong thư mục temp. (Như trong pic trên)

enter image description here

làm thế nào tôi có thể tái kích thước hình ảnh đầy đủ? những gì tôi bị mất ở đây?

EDIT: Như đã đề cập trong câu trả lời ở trên như đã đề cập bởi Erti-Chris Eelmaa tôi đã thay đổi mã như sau. và nó hoạt động ......

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

Bạn cần thay đổi chiều cao và chiều rộng của bitmap sau khi tạo. Những gì bạn đang làm ở đây là bạn đang tạo một Bitmap mới có kích thước nhỏ và điền nó với ảnh gốc mà không thay đổi kích cỡ. Bạn tạo một bitmap kích thước ban đầu và sau đó sử dụng chiều cao và chiều rộng của nó để thay đổi kích thước của nó. –

+0

@FaisalHafeez bạn có thể giải thích thêm về nó không? Làm thế nào tôi có thể tái kích thước nó – DevT

+0

Ở đây bạn đang tạo một bitmap có chiều rộng và chiều cao. Bây giờ đây là kích thước giảm. Nhưng khi bạn sẽ điền nó với hình ảnh, nó sẽ sao chép chỉ một phần của hình ảnh (điều này đang xảy ra trong trường hợp của bạn). Bạn cần sử dụng một số chức năng khác để thực hiện điều này. –

Trả lời

14

Chỉ cần sử dụng phương pháp này để lấy BitmapFrame, sau đó bạn có thể lưu nó vào HDD bằng PngBitmapEncoder.

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

tôi đã sử dụng hàm này và u có nghĩa là thay vì 'RenderTargetBitmap' sử dụng' PngBitmapEncoder' r8? nếu vậy làm thế nào tôi có thể lưu 'enc.Frames.Add (BitmapFrame.Create (rtb));' bởi vì ở đây nó cần đối tượng trực quan. – DevT

+0

tôi đã chỉnh sửa câu hỏi của mình. khi tôi tiết kiệm như vậy nó sẽ tiết kiệm hình ảnh màu đen. tại sao vậy? – DevT

+0

có thể giải quyết được sự cố. cảm ơn.... – DevT

14

Như để thay đổi kích thước riêng của mình, sử dụng WPF của TransformedBitmap dường như dễ dàng hơn một chút:

var bitmap = new TransformedBitmap(bitmapSource, 
    new ScaleTransform(
     newWidth/bitmapSource.PixelWidth, 
     newHeight/bitmapSource.PixelHeight)); 
Các vấn đề liên quan