简体   繁体   中英

Windows Phone 8 - change color in bitmap

如何将位图的一种颜色更改为另一种颜色?

Your solution uses GetPixel and SetPixel methods which are really slow. You can get the same result much faster working on pixels directly. But before that we have to know how to convert Color to int, because pixels in WriteableBitmap are represented by int array.

Some of my apps use this method to manipulate pixels and I wanted to do it as fast as possible, so never use SetPixel or GetPixel (eg. MC Skin Editor , MC Skin Viewer ).

To convert Color to int I made this simple extension:

public static int ToInt(this Color color)
{
    return unchecked((int)((color.A << 24) | (color.R << 16) | (color.G << 8) | color.B));
}

So now, your method could look like this:

public static WriteableBitmap ChangeColor(WriteableBitmap writeableBitmapOriginal, Color originalColor, Color newColor)
{
    var writeableBitmapNew = new WriteableBitmap(writeableBitmapOriginal);
    originalColorInt = originalColor.ToInt();
    newColorInt = newColor.ToInt();

    for (int i = 0; i < writeableBitmapNew.Pixels.Length; i++)
        if (writeableBitmapNew.Pixels[i] == originalColorInt)
            writeableBitmapNew.Pixels[i] = newColorInt;
    return writeableBitmapNew;
}

First, this is method which takes WritableBitmap a change color of your choice with another.

    public static WriteableBitmap ChangeColor(WriteableBitmap writeableBitmapOriginal, Color originalColor, Color newColor)
    {
        var writeableBitmapNew = new WriteableBitmap(writeableBitmapOriginal);

        for (int i = 0; i < writeableBitmapNew.PixelWidth; i++)
        {
            for (int j = 0; j < writeableBitmapNew.PixelHeight; j++)
            {                    
                if (writeableBitmapOriginal.GetPixel(i, j).Equals(originalColor))
                {
                    writeableBitmapNew.SetPixel(i, j, newColor);
                }
            }
        }
        return writeableBitmapNew;
    }  

The imports for this method:

using System.Windows.Media;
using System.Windows.Media.Imaging;

I also add how to instantly use this method, because loading of BitmapImage can be quite annoying (it is not loaded instantly from URI, therefore you can easily get NullPointer exception, thats why I am using things like StreamResourceInfo)

Uri uri = new Uri("Assets/Icons/ic_black_star_fav.png", UriKind.Relative);
StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
BitmapImage img = new BitmapImage();
img.SetSource(resourceInfo.Stream);
WriteableBitmap wbm = new WriteableBitmap(img);
WriteableBitmap newWbm = YourClassWithThisMethod.ChangeColor(wbm,Color.FromArgb(255, 0, 0, 0), Color.FromArgb(255, 255, 0, 0));

The code above load picture, and changes black non-transparent color into the red and put it into variable newWbm .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM