【问题标题】:Expand canvas/transparent background in BitmapImage in a WPF app在 WPF 应用程序中展开 BitmapImage 中的画布/透明背景
【发布时间】:2011-06-08 12:58:56
【问题描述】:

这是Save image to file keeping aspect ration in a WPF app的后续问题

我知道如何缩放图像,但是如何扩展画布大小,以确保图像仍然具有请求的宽度和高度。在这个例子中,它是 250x250,但它是动态的。

我创建了这个插图来展示我想要帮助的东西。

我找不到任何方法来扩展 BitmapImage 的画布,也找不到在内存中以正确大小创建具有透明背景的图像,然后将两个图像合并在一起的方法。

【问题讨论】:

    标签: c# .net wpf c#-4.0


    【解决方案1】:

    CroppedBitmap 似乎不支持在图像周围添加空间,因此您可以使用WriteableBitmap 创建正确大小的透明图像。如果输入小于目标大小,这个方法会放大它,但是很容易改变。

    public static BitmapSource FitImage(BitmapSource input, int width, int height)
    {
        if (input.PixelWidth == width && input.PixelHeight == height)
            return input;
    
        if(input.Format != PixelFormats.Bgra32 || input.Format != PixelFormats.Pbgra32)
            input = new FormatConvertedBitmap(input, PixelFormats.Bgra32, null, 0);
    
        //Use the same scale for x and y to keep aspect ratio.
        double scale = Math.Min((double)width / input.PixelWidth, height / (double)input.PixelHeight);
    
        int x = (int)Math.Round((width - (input.PixelWidth * scale))/2);
        int y = (int)Math.Round((height - (input.PixelHeight * scale))/2);
    
    
        var scaled = new TransformedBitmap(input, new ScaleTransform(scale, scale));
        var stride = scaled.PixelWidth * (scaled.Format.BitsPerPixel / 8);
    
        var result = new WriteableBitmap(width, height, input.DpiX, input.DpiY, input.Format,null);
    
        var data = new byte[scaled.PixelHeight * stride];
        scaled.CopyPixels(data, stride, 0);
        result.WritePixels(new Int32Rect(0,0,scaled.PixelWidth,scaled.PixelHeight), data, stride,x,y);
        return result;
    }
    

    如果您已经在使用 RenderTargetBitmap 渲染内容,则可以将其包装在 ViewBox 中进行缩放,但如果您只是使用普通图像,我会使用上述方法。

    【讨论】:

    • @Kris 这听起来很有希望。我是这些方法的新手。你能告诉我 BitmapSource 和 BitmapFrame 之间的区别吗?我正在使用 BitmapFrame 调整图像大小。
    • @Kris 好的,我看到 BitmapFrame 是 BitmapSource 的子级。所以应该能够使代码适应工作。现在就在尝试自己。
    • BitmapFrame 的主要用途是因为某些图像格式(如 gif)可以有多个帧,它还将其绑定到解码器并提供缩略图,为了更好的解释,请参阅 stackoverflow.com/questions/155391/…
    • @Kris +50 谢谢。整理出来。您的功能很棒,可以逐字复制。我使用的是使用 PostedFile.InputStream 转换为 BitmapFrame。因为 BitmapFrame 是 BitmapSource 的子对象,所以它被正确解析,但返回对象是 BitmapSource 而不是 BitmapFrame。为了保存它,我必须使用 BitmapFrame.Create(myBitmapSource) 将它转换回 BitmapFrame。这似乎效率低下。有没有更好的办法?
    • 编辑——我最初的评论被破坏了。我很兴奋能得到答案。您的功能很棒,可以逐字复制。就我而言,我正在处理来自表单上传的图像。这给了我 myFile.PostedFile.InputStream,可以通过调用 ReadBitmapFrame(myFile) 将其转换为 BitmapFrame。然后可以将其直接传递到您的函数中进行处理。不幸的是,您的函数的输出是 BitmapSource,我无法弄清楚如何使用 encoder.Save 进行保存。所以我使用 BitmapFrame.Create() 将 BitmapSource 转换回帧。
    【解决方案2】:

    只是一些代码,以防其他人尝试从表单上传中对文件进行后处理。

    if (file.PostedFile != null)
    {
        //write the new file to disk
        string cachePath = String.Format("{0}temp\\", Request.PhysicalApplicationPath);
        string photoPath = String.Format("{0}temp.png", cachePath);                
        if (!Directory.Exists(cachePath))
    {
       Directory.CreateDirectory(cachePath);
    }    
    
    file.PostedFile.SaveAs(photoPath);
    
    //resize the new file and save it to disk               
    BitmapSource banana = FitImage(ReadBitmapFrame(file.PostedFile.InputStream), 640, 480);
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(banana));
    FileStream pngStream = new FileStream(cachePath + "test.png", FileMode.Create);
    encoder.Save(pngStream);
    pngStream.Close();
    
    //set a couple images on page to the newly uploaded and newly processed files
    image.Src = "temp/temp.png";
    image.Visible = true;
    image2.Src = "temp/test.png"; 
    
    
       image2.Visible = true;
    }
    

    【讨论】:

      【解决方案3】:

      您应该能够将Stretch 属性设置为Uniform。

      【讨论】:

      • 如何从画布上保存图像?
      • 你有没有机会创建一个小例子来说明这一点?正如您在我之前的问题中所说的那样,我没有使用画布,而是将图像加载到 BitmapImage 中,然后将其加载到 TransformedBitmap 中以缩小它,但这只是没有给出正确的输出大小。跨度>
      猜你喜欢
      • 2016-04-21
      • 2012-08-24
      • 2015-03-18
      • 2022-11-15
      • 2012-04-02
      • 1970-01-01
      • 2016-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多