如何轻松地将ColorFilter应用于位图,图像,无论如何。在Android上,这是一个单行:myDrawable.setColorFilter(Color.GRAY, Mode.SRC_IN);
对于Windows,我只发现顶部编译样本的巨人以各种方式操纵图像。这对我的需求来说太过分了。我不想一次或类似地操纵每个像素,我只有一个带有白色图标的图像,我希望它变成绿色或者以编程方式。
答案 0 :(得分:0)
您可以使用新的Composition API对任何视觉效果都相当容易 - 您可以在此处查看此代码https://github.com/Microsoft/WindowsUIDevLabs/blob/master/Demos/EffectEditor/MainPage.xaml.cs(请参阅色调/色调效果)
答案 1 :(得分:0)
花了很多时间在MSDN和S / O上闲逛之后,我拼凑了下面的课程。它没有使用WriteableBitmapEx或任何超出Microsoft已提供的库。
这个答案在技术上只有一种混合模式可用; SRC_ATOP。如果像素不透明(alpha 0),这将迭代每个像素并用指定的色调颜色替换颜色值。
正如我所看到的许多答案所述;这将是非常缓慢的,除了应用一次性色调(即在您的应用程序启动时),不推荐用于任何其他任何事情。如果颜色不会经常变化,您可能希望将结果保存到本地文件,而不是每次都应用色调。
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;
}
}
}
快乐编码^ _ ^
参考文献:
答案 2 :(得分:0)
尽管不是直接回答,因为您询问了BitmapImage
的更一般情况,但仍然值得注意的是,很多时候您都需要使用图标来着色。如果您实际使用的是BitmapIcon
,则可以随意更改其Foreground
,并且可以获得与Android相同的支持。