BitmapUtils.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows.Media.Imaging;
  4. using PixiEditor.Models.Layers;
  5. using PixiEditor.Models.Position;
  6. using Color = System.Windows.Media.Color;
  7. namespace PixiEditor.Models.ImageManipulation
  8. {
  9. public static class BitmapUtils
  10. {
  11. /// <summary>
  12. /// Converts pixel bytes to WriteableBitmap.
  13. /// </summary>
  14. /// <param name="currentBitmapWidth">Width of bitmap.</param>
  15. /// <param name="currentBitmapHeight">Height of bitmap.</param>
  16. /// <param name="byteArray">Bitmap byte array.</param>
  17. /// <returns>WriteableBitmap.</returns>
  18. public static WriteableBitmap BytesToWriteableBitmap(int currentBitmapWidth, int currentBitmapHeight, byte[] byteArray)
  19. {
  20. WriteableBitmap bitmap = BitmapFactory.New(currentBitmapWidth, currentBitmapHeight);
  21. bitmap.FromByteArray(byteArray);
  22. return bitmap;
  23. }
  24. /// <summary>
  25. /// Converts layers bitmaps into one bitmap.
  26. /// </summary>
  27. /// <param name="layers">Layers to combine.</param>
  28. /// <param name="width">Width of final bitmap.</param>
  29. /// <param name="height">Height of final bitmap.</param>
  30. /// <returns>WriteableBitmap of layered bitmaps.</returns>
  31. public static WriteableBitmap CombineLayers(Layer[] layers, int width, int height)
  32. {
  33. WriteableBitmap finalBitmap = BitmapFactory.New(width, height);
  34. using (finalBitmap.GetBitmapContext())
  35. {
  36. for (int i = 0; i < layers.Length; i++)
  37. {
  38. float layerOpacity = layers[i].Opacity;
  39. for (int y = 0; y < finalBitmap.Height; y++)
  40. {
  41. for (int x = 0; x < finalBitmap.Width; x++)
  42. {
  43. Color color = layers[i].GetPixelWithOffset(x, y);
  44. if (i > 0 && ((color.A < 255 && color.A > 0) || (layerOpacity < 1f && layerOpacity > 0 && color.A > 0)))
  45. {
  46. var lastLayerPixel = finalBitmap.GetPixel(x, y);
  47. byte pixelA = (byte)(color.A * layerOpacity);
  48. byte r = (byte)((color.R * pixelA / 255) + (lastLayerPixel.R * lastLayerPixel.A * (255 - pixelA) / (255 * 255)));
  49. byte g = (byte)((color.G * pixelA / 255) + (lastLayerPixel.G * lastLayerPixel.A * (255 - pixelA) / (255 * 255)));
  50. byte b = (byte)((color.B * pixelA / 255) + (lastLayerPixel.B * lastLayerPixel.A * (255 - pixelA) / (255 * 255)));
  51. byte a = (byte)(pixelA + (lastLayerPixel.A * (255 - pixelA) / 255));
  52. color = Color.FromArgb(a, r, g, b);
  53. }
  54. else
  55. {
  56. color = Color.FromArgb(color.A, color.R, color.G, color.B);
  57. }
  58. if (color.A > 0)
  59. {
  60. finalBitmap.SetPixel(x, y, color);
  61. }
  62. }
  63. }
  64. }
  65. }
  66. return finalBitmap;
  67. }
  68. public static Dictionary<Guid, Color[]> GetPixelsForSelection(IEnumerable<Layer> layers, Coordinates[] selection)
  69. {
  70. Dictionary<Guid, Color[]> result = new Dictionary<Guid, Color[]>();
  71. foreach (Layer layer in layers)
  72. {
  73. Color[] pixels = new Color[selection.Length];
  74. using (layer.LayerBitmap.GetBitmapContext())
  75. {
  76. for (int j = 0; j < pixels.Length; j++)
  77. {
  78. Coordinates position = layer.GetRelativePosition(selection[j]);
  79. if (position.X < 0 || position.X > layer.Width - 1 || position.Y < 0 ||
  80. position.Y > layer.Height - 1)
  81. {
  82. continue;
  83. }
  84. pixels[j] = layer.GetPixel(position.X, position.Y);
  85. }
  86. }
  87. result[layer.LayerGuid] = pixels;
  88. }
  89. return result;
  90. }
  91. }
  92. }