2016-07-05 6 views
1

ColorFilter를 easly 어떻게 비트 맵, 이미지에 적용 할 수 있습니까? 안드로이드에서 이것은 하나의 라이너입니다 : myDrawable.setColorFilter(Color.GRAY, Mode.SRC_IN); Windows의 경우 나는 모든면에서 이미지를 조작하기 위해 최고로 압축 된 샘플을 찾았습니다. 그건 내 필요에 너무 비싸다. 한번에 모든 픽셀을 조작하고 싶지는 않습니다. 흰색 아이콘이있는 이미지가 있습니다. 그러면이 이미지가 녹색으로 프로그래밍되기를 원합니다.UWP ColorFilter를 BitmapImage에 적용하십시오.

답변

0

(색조/색조 효과 참조) 많은 시간이 MSDN 및 S/O 주위를 배회 보낸 후 나는 다음과 같은 수업을 함께했다. WriteableBitmapEx 또는 Microsoft에서 이미 제공 한 것 이상의 라이브러리는 사용하지 않습니다.

이 대답에는 기술적으로 단 하나의 혼합 모드 만 있습니다. SRC_ATOP. 픽셀이 투명하지 않은 경우 (알파 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; 
     } 

    } 
} 

해피 코딩^_^

참고 :

WriteableBitmap to byte array

Set a pixel in WriteableBitmap

How to create WriteableBitmap from BitmapImage