ClipboardController.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System.IO;
  2. using System.Linq;
  3. using System.Linq.Expressions;
  4. using Avalonia;
  5. using Avalonia.Input;
  6. using Avalonia.Input.Platform;
  7. using Avalonia.Media.Imaging;
  8. using AvaloniaWriteableBitmapEx;
  9. using PixiEditor.Models.ImageManipulation;
  10. using PixiEditor.Models.Layers;
  11. using PixiEditor.Models.Position;
  12. using SharpDX.WIC;
  13. namespace PixiEditor.Models.Controllers
  14. {
  15. public static class ClipboardController
  16. {
  17. /// <summary>
  18. /// Copies selection to clipboard in PNG, Bitmap and DIB formats.
  19. /// </summary>
  20. /// <param name="layers">Layers where selection is</param>
  21. /// <param name="selection"></param>
  22. /// <param name="originalImageWidth">Output </param>
  23. /// <param name="originalImageHeight"></param>
  24. public static void CopyToClipboard(Layer[] layers, Coordinates[] selection, int originalImageWidth, int originalImageHeight)
  25. {
  26. var clipboard = (IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard));
  27. WriteableBitmap combinedBitmaps = BitmapUtils.CombineLayers(layers, originalImageWidth, originalImageHeight);
  28. using (var pngStream = new MemoryStream())
  29. {
  30. DataObject data = new ClipboardDataObject();
  31. var croppedBmp = BitmapSelectionToBmpSource(combinedBitmaps, selection);
  32. data.SetData(DataFormats.Bitmap, croppedBmp, true); //Bitmap, no transparency support
  33. using (var bmpData = croppedBmp.Lock())
  34. {
  35. var format = PixelFormat.FormatDontCare;
  36. PngBitmapEncoder encoder = new PngBitmapEncoder(new ImagingFactory(bmpData.Address), pngStream);
  37. BitmapFrameEncode frameEncode = new BitmapFrameEncode(encoder);
  38. frameEncode.Initialize();
  39. frameEncode.SetSize(bmpData.Size.Width, bmpData.Size.Height);
  40. frameEncode.SetPixelFormat(ref format);
  41. frameEncode.WritePixels(bmpData.Size.Height, new SharpDX.DataRectangle(bmpData.Address, 4 * sizeof(ushort)));
  42. frameEncode.Commit();
  43. encoder.Commit();
  44. data.SetData("PNG", pngStream, false); //PNG, supports transparency
  45. Clipboard.SetImage(croppedBmp); //DIB format
  46. Clipboard.SetDataObject(data, true);
  47. }
  48. }
  49. }
  50. /// <summary>
  51. /// Pastes image from clipboard into new layer.
  52. /// </summary>
  53. public static void PasteFromClipboard()
  54. {
  55. WriteableBitmap image = GetImageFromClipboard();
  56. if (image != null) AddImageToLayers(image);
  57. }
  58. /// <summary>
  59. /// Gets image from clipboard, supported PNG, Dib and Bitmap
  60. /// </summary>
  61. /// <returns>WriteableBitmap</returns>
  62. public static WriteableBitmap GetImageFromClipboard()
  63. {
  64. DataObject dao = (DataObject)Clipboard.GetDataObject();
  65. WriteableBitmap finalImage = null;
  66. if (dao.GetDataPresent("PNG"))
  67. using (MemoryStream pngStream = dao.GetData("PNG") as MemoryStream)
  68. {
  69. if (pngStream != null)
  70. {
  71. var imagingFactory = new ImagingFactory2();
  72. PngBitmapDecoder decoder = new PngBitmapDecoder(imagingFactory);
  73. decoder.Initialize(new WICStream(new ImagingFactory2(), pngStream), DecodeOptions.CacheOnLoad);
  74. var frame = decoder.GetFrame(0);
  75. byte[] output = new byte[4 * frame.Size.Width * frame.Size.Height];
  76. frame.CopyPixels(output, 4);
  77. return BitmapFactory.New(frame.Size.Width, frame.Size.Height).FromByteArray(output);
  78. }
  79. }
  80. else if (dao.GetDataPresent(DataFormats.Dib))
  81. finalImage = new WriteableBitmap(Clipboard.GetImage()!);
  82. else if (dao.GetDataPresent(DataFormats.Bitmap))
  83. finalImage = new WriteableBitmap((dao.GetData(DataFormats.Bitmap) as BitmapSource)!);
  84. return finalImage;
  85. }
  86. public static bool IsImageInClipboard()
  87. {
  88. DataObject dao = (DataObject)Application.Current.Clipboard.GetDataObject();
  89. if (dao == null) return false;
  90. return dao.Contains("PNG") || dao.Contains("Dib") ||
  91. dao.Contains("Bitmap");
  92. }
  93. private static void AddImageToLayers(WriteableBitmap image)
  94. {
  95. ViewModelMain.Current.BitmapManager.AddNewLayer("Image", image);
  96. }
  97. public static WriteableBitmap BitmapSelectionToBmpSource(WriteableBitmap bitmap, Coordinates[] selection)
  98. {
  99. int offsetX = selection.Min(x => x.X);
  100. int offsetY = selection.Min(x => x.Y);
  101. int width = selection.Max(x => x.X) - offsetX + 1;
  102. int height = selection.Max(x => x.Y) - offsetY + 1;
  103. return bitmap.Crop(offsetX, offsetY, width, height);
  104. }
  105. }
  106. }