【问题标题】:WPF Save Photo EffectWPF 保存照片效果
【发布时间】:2014-01-22 02:58:18
【问题描述】:

所以我有代码来保存我用投影编辑的图像,在我保存后我发现代码只保存图像大小的文件。我需要的是要么用新的保存具有效果的尺寸(例如,由于其下方的阴影,图像的尺寸应该变大)。 我不知道如何编辑代码以保存更大的图像。如果图像静态更大,那真的没问题,我不介意它是否保存图像的大小 + 每种大小的 20 像素。

try
{
    Microsoft.Win32.SaveFileDialog saveDialog = new Microsoft.Win32.SaveFileDialog();
    saveDialog.Filter = "JPeg Image(*.JPG)|*.jpg|Bitmap Image(*.BMP)|*.bmp|Png Image(*.PNG)|*.png|Gif Image(*.GIF)|*.gif";
    if (saveDialog.ShowDialog().Value == true)
    {
        // Save current canvas transform
        Transform transform = image1.LayoutTransform;
        // reset current transform (in case it is scaled or rotated)
        image1.LayoutTransform = null;

        // Get the size of canvas
        Size size = new Size(image1.ActualWidth, image1.ActualHeight);
        // Measure and arrange the surface
        // VERY IMPORTANT
        image1.Measure(size);
        image1.Arrange(new Rect(size));

        // Create a render bitmap and push the surface to it
        RenderTargetBitmap renderBitmap =
          new RenderTargetBitmap(
            (int)size.Width,
            (int)size.Height,
            96d,
            96d,
            PixelFormats.Default);
        renderBitmap.Render(image1);
        BitmapEncoder encoder = new BmpBitmapEncoder();
        string extension = saveDialog.FileName.Substring(saveDialog.FileName.LastIndexOf('.'));
        switch (extension.ToLower())
        {
            case ".jpg":
                encoder = new JpegBitmapEncoder();
                break;
            case ".bmp":
                encoder = new BmpBitmapEncoder();
                break;
            case ".gif":
                encoder = new GifBitmapEncoder();
                break;
            case ".png":
                encoder = new PngBitmapEncoder();
                break;
        }
        // push the rendered bitmap to it
        encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
        // Create a file stream for saving image
        using (System.IO.FileStream fs = System.IO.File.Open(saveDialog.FileName, System.IO.FileMode.OpenOrCreate))
        {
            encoder.Save(fs);
        }
        // Restore previously saved layout
        image1.LayoutTransform = transform;
    }

}
catch (Exception)
{

    throw;
}

【问题讨论】:

    标签: c# wpf bitmap save effect


    【解决方案1】:

    请尝试在对System.IO.File.Open() 的调用中使用FileMode.Create 而不是FileMode.OpenOrCreate

    【讨论】:

    • 我更改了它,但仍然没有解决我的问题...我不知道为什么会这样
    【解决方案2】:

    如果您的意思是您在 WPF 中为图像添加了“位图效果”或“着色器”,则结果是可以预期的,因为这些不是布局过程的一部分,也没有计入“ActualWidth/实际高度”。您可以在创建新图像时添加一些单位:

    Size size = new Size(image1.ActualWidth + 20, image1.ActualHeight + 20);
    

    如果“image1”对象的其他布局属性是正确的,这应该可以解决问题。

    编辑:我建议使用新控件来呈现图像,而不是使用已经属于不同可视化树的控件。布局/渲染可能会产生各种奇怪的副作用。下面是一段适用于投影效果的代码:

    编辑 2:将“效果”属性设置为与 UI 中相同的对象...

            try
            {
                Microsoft.Win32.SaveFileDialog saveDialog = new Microsoft.Win32.SaveFileDialog();
                saveDialog.Filter = "JPeg Image(*.JPG)|*.jpg|Bitmap Image(*.BMP)|*.bmp|Png Image(*.PNG)|*.png|Gif Image(*.GIF)|*.gif";
                if (saveDialog.ShowDialog().Value == true)
                {
                    Image image2 = new Image();
                    image2.Source = image1.Source;
                    Grid container = new Grid();
                    container.Children.Add(image2);
                    container.Background = new SolidColorBrush(Colors.White);
                    image2.Stretch = Stretch.None;
                    image2.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    image2.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
    
                    // Get the size of canvas
                    Size size = new Size(image2.Source.Width + 20, image2.Source.Height + 20);
                    // Measure and arrange the surface
                    // VERY IMPORTANT
                    container.Measure(size);
                    container.Arrange(new Rect(size));
    
                    // BitmapEffect is deprecated and buggy, use Effect instead.
    
                    // since the effect isn't part of the visual tree but independent,
                    // we can just reuse the same object as on the image in the UI.
                    image2.Effect = image1.Effect;
    
                    //image2.Effect = new DropShadowEffect
                    //{
                    //    Color = Colors.Black,
                    //    ShadowDepth = 5,
                    //    BlurRadius = 3,
                    //    Opacity = 1
                    //};
    
    
                    // Create a render bitmap and push the surface to it
                    RenderTargetBitmap renderBitmap =
                      new RenderTargetBitmap(
                        (int)size.Width,
                        (int)size.Height,
                        96d,
                        96d,
                        PixelFormats.Default);
    
                    renderBitmap.Render(container);
                    BitmapEncoder encoder = new BmpBitmapEncoder();
                    string extension = saveDialog.FileName.Substring(saveDialog.FileName.LastIndexOf('.'));
                    switch (extension.ToLower())
                    {
                        case ".jpg":
                            encoder = new JpegBitmapEncoder();
                            break;
                        case ".bmp":
                            encoder = new BmpBitmapEncoder();
                            break;
                        case ".gif":
                            encoder = new GifBitmapEncoder();
                            break;
                        case ".png":
                            encoder = new PngBitmapEncoder();
                            break;
                    }
                    // push the rendered bitmap to it
                    encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
                    // Create a file stream for saving image
                    using (System.IO.FileStream fs = System.IO.File.Open(saveDialog.FileName, System.IO.FileMode.OpenOrCreate))
                    {
                        encoder.Save(fs);
                    }
                }
    
            }
            catch (Exception)
            {
    
                throw;
            }
    

    另外,您使用剪贴板加载图像是否有原因?

    【讨论】:

    • 我尝试了你推荐的,最后得到了这个(请注意,如果我尝试在右边的水线上都使用 20,但它仍然只是那条线:img138.imageshack.us/img138/5682/ko7h.jpg 黑线总是出现在保存的文件(PNG 格式除外)。
    • 如果不确切知道“image1”是如何构造的以及它如何与应用程序的其余部分联系起来,就很难预测结果。黑色是新图像的“背景颜色”——它在 PNG 中是不可见的,因为它在那里是“透明的”。根据 image1 的上下文,有多种方法可以在渲染图像之前用白色(或任何其他颜色)填充新图像。
    • 嗯,我要找的只是周围有外发光效果的图片。
    • 我得到了那么多 - 但你必须明白位图 (PNG/JPG..) 没有“效果”只有像素。外部发光效果添加到图像的外部。所以它只能由查看应用程序应用,或者它必须是图像本身的一部分。如果它是图像的一部分,那么它所针对的“背景”也必须是图像的一部分。 IE。白色背景,图像 + 白色背景上的阴影。 JPG 输出看起来很奇怪,因为在保存操作之前,WPF 将使用保存时变得不透明的半透明像素。你能分享“image1”的代码吗?
    • 这是 XAML 代码,因为在 c# 代码中没有任何内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    相关资源
    最近更新 更多