如何轻松地将ColorFilter应用于位图,图像等。在Android上,这是一行代码:myDrawable.setColorFilter(Color.GRAY, Mode.SRC_IN);
对于Windows,我只找到了giant over top编译的样本来以各种方式处理图像。这对我来说太多了。我不想一次操作每个像素或类似的,我只是有一个白色图标的图像,我想把它变成绿色或其他编程
你可以使用新的合成api很容易地做到这一点,任何视觉-你可以看到这里的代码https://github.com/Microsoft/WindowsUIDevLabs/blob/master/Demos/EffectEditor/MainPage.xaml.cs(见色彩/色相效果)
在MSDN和S/O上花了很多时间之后,我拼凑了下面的类。它不使用WriteableBitmapEx或任何超出微软已经提供的库。
这个答案在技术上只有一种混合模式可用;SRC_ATOP。这将遍历每个像素,如果像素不透明(alpha 0),则将颜色值替换为指定的tint颜色。
正如我看到的许多答案所指出的那样;这将是相当缓慢的,不建议使用一次性色调(例如,在你的应用程序启动时)。如果颜色不会频繁变化,您可能希望将结果保存到本地文件,而不是每次都应用色彩。
using System;
using System.IO;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Xaml.Media.Imaging;
namespace Helpers
{
public class ImageManipulationHelper
{
public static async Task<WriteableBitmap> ApplyTint(Uri sourceUri, Color tintColour)
{
WriteableBitmap source = await GetImageFile(sourceUri);
byte[] byteArray = null;
using (Stream stream = source.PixelBuffer.AsStream())
{
long streamLength = stream.Length;
byteArray = new byte[streamLength];
await stream.ReadAsync(byteArray, 0, byteArray.Length);
if (streamLength > 0)
{
for (int i = 0; i < streamLength; i += 4)
{
// check the pixel is not transparent (BGRA)
if (byteArray[i + 3] != 0)
{
byteArray[i] = tintColour.B; // Blue
byteArray[i + 1] = tintColour.G; // Green
byteArray[i + 2] = tintColour.R; // Red
}
}
}
}
if (byteArray != null)
{
WriteableBitmap destination = await PixelBufferToWriteableBitmap(byteArray, source.PixelWidth, source.PixelHeight);
return destination;
}
return null;
}
private static async Task<WriteableBitmap> GetImageFile(Uri fileUri)
{
StorageFile imageFile = await StorageFile.GetFileFromApplicationUriAsync(fileUri);
WriteableBitmap writeableBitmap = null;
using (IRandomAccessStream imageStream = await imageFile.OpenReadAsync())
{
BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(imageStream);
BitmapTransform dummyTransform = new BitmapTransform();
PixelDataProvider pixelDataProvider =
await bitmapDecoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied, dummyTransform,
ExifOrientationMode.RespectExifOrientation,
ColorManagementMode.ColorManageToSRgb);
byte[] pixelData = pixelDataProvider.DetachPixelData();
writeableBitmap = new WriteableBitmap(
(int)bitmapDecoder.OrientedPixelWidth,
(int)bitmapDecoder.OrientedPixelHeight);
using (Stream pixelStream = writeableBitmap.PixelBuffer.AsStream())
{
await pixelStream.WriteAsync(pixelData, 0, pixelData.Length);
}
}
return writeableBitmap;
}
public static async Task PixelBufferToWriteableBitmap(WriteableBitmap wb, byte[] bgra)
{
using (Stream stream = wb.PixelBuffer.AsStream())
{
await stream.WriteAsync(bgra, 0, bgra.Length);
}
}
public static async Task<WriteableBitmap> PixelBufferToWriteableBitmap(byte[] bgra, int width, int height)
{
var wb = new WriteableBitmap(width, height);
await PixelBufferToWriteableBitmap(wb, bgra);
return wb;
}
}
}
Happy Coding ^_^
引用:
WriteableBitmap到字节数组
设置WriteableBitmap中的像素
如何从BitmapImage创建WriteableBitmap
虽然不是直接的答案,因为您问的是BitmapImage
的更一般的情况,但仍然值得注意的是,很多时候您需要使用图标进行这样的着色。如果你实际使用的是BitmapIcon
,你可以自由地改变它的Foreground
,你会得到同样的支持,你发现在Android。