【问题标题】:Convert a dynamic BitmapImage to a grayscale BitmapImage in a Windows Phone application在 Windows Phone 应用程序中将动态 BitmapImage 转换为灰度 BitmapImage
【发布时间】:2014-12-07 12:12:14
【问题描述】:

我想将 BitmapImage 转换为灰度 BitmapImage:我从一个方法中得到的,因此 - 宽度和高度对我来说是未知的。我曾尝试研究 WritableBitmapEx 和静态扩展方法等选项,但它们对我没有帮助,因为我希望返回数据类型为 BitmapImage,然后我需要将其添加到 List。

这可以在使用 C# 的 Windows Phone 应用程序中实现吗?如果有人能对此有所了解,我将不胜感激。谢谢。

【问题讨论】:

    标签: c# windows-phone-8 bitmapimage grayscale


    【解决方案1】:

    算法很简单:

    using System.Windows.Media.Imaging;
    using System.IO;
    
    private WriteableBitmap ConvertToGrayScale(BitmapImage source)
    {
        WriteableBitmap wb = new WriteableBitmap(source);               // create the WritableBitmap using the source
    
        int[] grayPixels = new int[wb.PixelWidth * wb.PixelHeight];
    
        // lets use the average algo 
        for (int x = 0; x < wb.Pixels.Length; x++)
        {
            // get the pixel
            int pixel = wb.Pixels[x];
    
            // get the component
            int red = (pixel & 0x00FF0000) >> 16;
            int blue = (pixel & 0x0000FF00) >> 8;
            int green = (pixel & 0x000000FF);
    
            // get the average
            int average = (byte)((red + blue + green) / 3);
    
            // assign the gray values keep the alpha
            unchecked
            {
                grayPixels[x] = (int)((pixel & 0xFF000000) | average << 16 | average << 8 | average);
            }
        }
    
    
    
        // copy grayPixels back to Pixels
        Buffer.BlockCopy(grayPixels, 0, wb.Pixels, 0, (grayPixels.Length * 4));
    
        return wb;            
    }
    
    private BitmapImage ConvertWBtoBI(WriteableBitmap wb)
    {
        BitmapImage bi;
        using (MemoryStream ms = new MemoryStream())
        {
            wb.SaveJpeg(ms, wb.PixelWidth, wb.PixelHeight, 0, 100);
            bi = new BitmapImage();
            bi.SetSource(ms);
        }
        return bi;
    }
    

    <Image x:Name="myImage" Source="/Assets/AlignmentGrid.png" Stretch="None" />
    

    private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
    {       
        WriteableBitmap wb = ConvertToGrayScale((BitmapImage)this.myImage.Source);
        BitmapImage bi = ConvertWBtoBI(wb);
    
    
        myImage.Source = bi;       
    }
    

    代码在行动:

    【讨论】:

    • 一如既往,我总是对您的所有答案感到满意 :) 因为它们总是很好用!虽然,我想分享另一个我在网上找到的答案,它的执行速度比你的答案快一点,我想知道为什么? MessageBox.Show((DateTime.Now - t1).ToString());
    • @NavikGoswami 没问题,我通常会编写没有任何优化的解决方案——我认为这样更容易理解。你可以做一些事情来加速我上面写的代码。我认为您打算发布一些代码,但是您的 cmets 被切断了。只需更新您的问题,稍后我会看一下。
    • 非常正确。是的,代码被截断了。但是无论如何,谢谢你帮助我!你也能回答这个问题吗 -> stackoverflow.com/questions/26316702/…
    【解决方案2】:

    不确定这里的命名空间,但类似这样的方法可能有效:

    using System;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    
    FormatConvertedBitmap bitmapGreyscale = new FormatConvertedBitmap(bitmap, PixelFormats.Gray8, BitmapPalettes.Gray256, 0.0);
    

    【讨论】:

    • 找不到命名空间FormatConvertedBitmap的类型。我认为 Windows Phone 不支持它:(
    • 您可以尝试在 Visual Studio 解决方案资源管理器中的项目引用中添加对 PresentationCore.dll 的引用。
    【解决方案3】:

    您不能写入 BitmapImage:您需要将其转换为 WriteableBitmap。一旦有了 WriteableBitmap,就可以轻松访问缓冲区并将像素转换为灰度。

    WriteableBitmaps 和 BitmapImages 的工作方式非常相似,因为它们都是 BitmapSources。如果您将列表创建为列表而不是列表,则可以将它们添加到同一个列表中

    应用不太可能对 List 的内容执行任何要求内容为 BitmapImages 而不是 BitmapSources 的操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 2016-07-14
      相关资源
      最近更新 更多