/// <summary> /// Saves the graphics using the specified save action. /// </summary> /// <example> /// graphics.Save(image => image.SaveAsJpeg("file.jpg")) /// </example> public static void Save(this Graphics graphics, Action <Image <Rgba32> > onSave) { var targetFormat = PixelFormat.Format_ABGR8888; var size = graphics.OutputSize; var pixelData = new ColorRGB888[graphics.PixelCount]; graphics.ReadPixels(ref pixelData); var pixelHandle = GCHandle.Alloc(pixelData, GCHandleType.Pinned); try { var image = new Image <Rgba32>(size.Width, size.Height); unsafe { fixed(void *target = &MemoryMarshal.GetReference(image.GetPixelSpan())) { Pixels.Convert(size.Width, size.Height, 4 * size.Width, 4 * size.Width, PixelFormat.Format_RGB888, targetFormat, pixelHandle.AddrOfPinnedObject(), (IntPtr)target); } } onSave(image); image.Dispose(); } finally { pixelHandle.Free(); } }
public void ShouldConvertPixels() { var width = 10; var height = 10; var count = width * height; var stride = width * 4; // 4 bytes per pixel var before = Enumerable.Repeat <ColorRGBA8888>( new ColorRGBA8888(Color.FromArgb(unchecked ((int)0xDEADBEEF))), count ).ToArray(); var after = new ColorARGB8888[count]; Pixels.Convert(width, height, stride, stride, ref before, ref after); ShouldBeEquivalent(before, after); }