/// <summary> /// Takes a Surface and quantizes it down to an 8-bit bitmap. /// </summary> /// <param name="quantizeMe">The Surface to quantize.</param> /// <param name="ditherAmount">How strong should dithering be applied. 0 for no dithering, 8 for full dithering. 7 is generally a good default to use.</param> /// <param name="maxColors">The maximum number of colors to use. This may range from 2 to 256.</param> /// <param name="enableTransparency">If true, then one color slot will be reserved for transparency. Any color with an alpha value less than 255 will be transparent in the output.</param> /// <param name="progressCallback">The progress callback delegate.</param> /// <returns>An 8-bit Bitmap that is the same size as quantizeMe.</returns> protected Bitmap Quantize(Surface quantizeMe, int ditherAmount, int maxColors, bool enableTransparency, ProgressEventHandler progressCallback) { if (ditherAmount < 0 || ditherAmount > 8) { throw new ArgumentOutOfRangeException( "ditherAmount", ditherAmount, "Out of bounds. Must be in the range [0, 8]"); } if (maxColors < 2 || maxColors > 256) { throw new ArgumentOutOfRangeException( "maxColors", maxColors, "Out of bounds. Must be in the range [2, 256]"); } // TODO: detect if transparency is needed? or take another argument using (Bitmap bitmap = quantizeMe.CreateAliasedBitmap(quantizeMe.Bounds, true)) { OctreeQuantizer quantizer = new OctreeQuantizer(maxColors, enableTransparency); quantizer.DitherLevel = ditherAmount; Bitmap quantized = quantizer.Quantize(bitmap, progressCallback); return(quantized); } }
/// <summary> /// Takes a Surface and quantizes it down to an 8-bit bitmap. /// </summary> /// <param name="quantizeMe">The Surface to quantize.</param> /// <param name="ditherAmount">How strong should dithering be applied. 0 for no dithering, 8 for full dithering.</param> /// <param name="maxColors">The maximum number of colors to use. This may range from 2 to 255.</param> /// <param name="progressCallback">The progress callback delegate.</param> /// <returns>An 8-bit Bitmap that is the same size as quantizeMe.</returns> protected Bitmap Quantize(Surface quantizeMe, int ditherAmount, int maxColors, ProgressEventHandler progressCallback) { if (ditherAmount < 0 || ditherAmount > 8) { throw new ArgumentOutOfRangeException( "ditherAmount", ditherAmount, "Out of bounds. Must be in the range [0, 8]"); } if (maxColors < 2 || maxColors > 255) { throw new ArgumentOutOfRangeException( "maxColors", maxColors, "Out of bounds. Must be in the range [2, 255]"); } using (Bitmap bitmap = quantizeMe.CreateAliasedBitmap(quantizeMe.Bounds, true)) { OctreeQuantizer quantizer = new OctreeQuantizer(maxColors, 8); quantizer.DitherLevel = ditherAmount; Bitmap quantized = quantizer.Quantize(bitmap, progressCallback); return(quantized); } }
public FastBitmap(int width, int height, ColorBgra backgroundColor) { surface = new Surface(width, height); bitmap = surface.CreateAliasedBitmap(); graphics = Graphics.FromImage(bitmap); background = new uint[width * height]; for (int i = 0; i < width * height; ++i) { background[i] = backgroundColor.Bgra; } }
public static void Save(Document input, Stream output, Surface scratchSurface, ImageFormat format, ProgressEventHandler callback) { // flatten the document scratchSurface.Clear(ColorBgra.FromBgra(0, 0, 0, 0)); using (RenderArgs ra = new RenderArgs(scratchSurface)) { input.Render(ra, true); } using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap()) { LoadProperties(bitmap, input); bitmap.Save(output, format); } }
protected override void OnSaveT(Document input, Stream output, PropertyBasedSaveConfigToken token, Surface scratchSurface, ProgressEventHandler progressCallback) { int quality = token.GetProperty<Int32Property>(PropertyNames.Quality).Value; ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Jpeg); EncoderParameters parms = new EncoderParameters(1); EncoderParameter parm = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); parms.Param[0] = parm; scratchSurface.Clear(ColorBgra.White); using (RenderArgs ra = new RenderArgs(scratchSurface)) { input.Render(ra, false); } using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap()) { GdiPlusFileType.LoadProperties(bitmap, input); bitmap.Save(output, icf, parms); } }
protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback) { JpegSaveConfigToken jsct = (JpegSaveConfigToken)token; ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Jpeg); EncoderParameters parms = new EncoderParameters(1); EncoderParameter parm = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, jsct.Quality); // force '95% quality' parms.Param[0] = parm; scratchSurface.Clear(ColorBgra.White); using (RenderArgs ra = new RenderArgs(scratchSurface)) { input.Render(ra, true); } using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap()) { GdiPlusFileType.LoadProperties(bitmap, input); bitmap.Save(output, icf, parms); } }
public override unsafe MaskedSurface TryGetMaskedSurface(IWin32Window window, IPdnDataObject clipData) { Surface result = null; using (PaintDotNet.SystemLayer.Clipboard.Transaction transaction = PaintDotNet.SystemLayer.Clipboard.Open(window)) { bool flag = transaction.TryGetRawNativeData(8, delegate(UnsafeBufferLock buffer) { Size size; byte *pBitmapInfo = (byte *)buffer.Address; int ncbBitmapInfo = (int)buffer.Size; if (PdnGraphics.TryGetBitmapInfoSize(pBitmapInfo, ncbBitmapInfo, out size)) { Surface disposeMe = new Surface(size.Width, size.Height); bool flag = false; try { using (Bitmap bitmap = disposeMe.CreateAliasedBitmap(true)) { flag = PdnGraphics.TryCopyFromBitmapInfo(bitmap, pBitmapInfo, ncbBitmapInfo); } disposeMe.DetectAndFixDishonestAlpha(); } finally { if (flag) { result = disposeMe; } else { DisposableUtil.Free <Surface>(ref disposeMe); } } } }); } return(ClipboardUtil.ClipboardRetriever.ConvertToMaskedSurface(ref result)); }
protected override void OnSaveT(Document input, Stream output, PropertyBasedSaveConfigToken token, Surface scratchSurface, ProgressEventHandler progressCallback) { int quality = token.GetProperty <Int32Property>(PropertyNames.Quality).Value; ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Jpeg); EncoderParameters parms = new EncoderParameters(1); EncoderParameter parm = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); parms.Param[0] = parm; scratchSurface.Clear(ColorBgra.White); using (RenderArgs ra = new RenderArgs(scratchSurface)) { input.Render(ra, false); } using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap()) { GdiPlusFileType.LoadProperties(bitmap, input); bitmap.Save(output, icf, parms); } }
/// <summary> /// Takes a Surface and quantizes it down to an 8-bit bitmap. /// </summary> /// <param name="quantizeMe">The Surface to quantize.</param> /// <param name="ditherAmount">How strong should dithering be applied. 0 for no dithering, 8 for full dithering.</param> /// <param name="maxColors">The maximum number of colors to use. This may range from 2 to 255.</param> /// <param name="progressCallback">The progress callback delegate.</param> /// <returns>An 8-bit Bitmap that is the same size as quantizeMe.</returns> protected Bitmap Quantize(Surface quantizeMe, int ditherAmount, int maxColors, ProgressEventHandler progressCallback) { if (ditherAmount < 0 || ditherAmount > 8) { throw new ArgumentOutOfRangeException( "ditherAmount", ditherAmount, "Out of bounds. Must be in the range [0, 8]"); } if (maxColors < 2 || maxColors > 255) { throw new ArgumentOutOfRangeException( "maxColors", maxColors, "Out of bounds. Must be in the range [2, 255]"); } using (Bitmap bitmap = quantizeMe.CreateAliasedBitmap(quantizeMe.Bounds, true)) { OctreeQuantizer quantizer = new OctreeQuantizer(maxColors, 8); quantizer.DitherLevel = ditherAmount; Bitmap quantized = quantizer.Quantize(bitmap, progressCallback); return quantized; } }
private static BitmapEx resize(Bitmap bitmap, int width, int height, Rectangle? clipRectangle) { using (var src = Surface.CopyFromBitmap(bitmap)) { var dest = new Surface(width, height); BitmapEx res = new BitmapEx(); res.surface = dest; dest.FitSurface(ResamplingAlgorithm.SuperSampling, src); if (clipRectangle == null) res.Bitmap = dest.CreateAliasedBitmap(); else res.Bitmap = dest.CreateAliasedBitmap(clipRectangle.Value); return res; } }
internal override unsafe void FinalSave( Document input, Stream output, Surface scratchSurface, int ditherLevel, SavableBitDepths bitDepth, PropertyBasedSaveConfigToken token, ProgressEventHandler progressCallback) { if (bitDepth == SavableBitDepths.Rgba32) { ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Png); EncoderParameters parms = new EncoderParameters(1); EncoderParameter parm = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 32); parms.Param[0] = parm; using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap()) { GdiPlusFileType.LoadProperties(bitmap, input); bitmap.Save(output, icf, parms); } } else if (bitDepth == SavableBitDepths.Rgb24) { // In order to save memory, we 'squish' the 32-bit bitmap down to 24-bit in-place // instead of allocating a new bitmap and copying it over. SquishSurfaceTo24Bpp(scratchSurface); ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Png); EncoderParameters parms = new EncoderParameters(1); EncoderParameter parm = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 24); parms.Param[0] = parm; using (Bitmap bitmap = CreateAliased24BppBitmap(scratchSurface)) { GdiPlusFileType.LoadProperties(bitmap, input); bitmap.Save(output, icf, parms); } } else if (bitDepth == SavableBitDepths.Rgb8) { using (Bitmap quantized = Quantize(scratchSurface, ditherLevel, 256, false, progressCallback)) { ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Png); EncoderParameters parms = new EncoderParameters(1); EncoderParameter parm = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8); parms.Param[0] = parm; GdiPlusFileType.LoadProperties(quantized, input); quantized.Save(output, icf, parms); } } else if (bitDepth == SavableBitDepths.Rgba8) { using (Bitmap quantized = Quantize(scratchSurface, ditherLevel, 256, true, progressCallback)) { ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Png); EncoderParameters parms = new EncoderParameters(1); EncoderParameter parm = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8); parms.Param[0] = parm; GdiPlusFileType.LoadProperties(quantized, input); quantized.Save(output, icf, parms); } } else { throw new InvalidEnumArgumentException("bitDepth", (int)bitDepth, typeof(SavableBitDepths)); } }
private static unsafe Surface GetClipboardImageAsSurface(IWin32Window currentWindow, IPdnDataObject clipData) { Image image = null; Surface surface = null; if (((image == null) && (surface == null)) && clipData.GetDataPresent(PdnDataObjectFormats.FileDrop)) { try { string[] strArray = null; using (PaintDotNet.SystemLayer.Clipboard.Transaction transaction = PaintDotNet.SystemLayer.Clipboard.Open(currentWindow)) { strArray = transaction.TryGetFileDropData(); } if ((strArray != null) && (strArray.Length == 1)) { string fileName = strArray[0]; if (IsImageFileName(fileName) && File.Exists(fileName)) { image = Image.FromFile(fileName); surface = Surface.CopyFromGdipImage(image, false); image.Dispose(); image = null; } } } catch (OutOfMemoryException) { throw; } catch (Exception) { } } if (((image == null) && (surface == null)) && clipData.GetDataPresent(PdnDataObjectFormats.Dib, true)) { try { using (PaintDotNet.SystemLayer.Clipboard.Transaction transaction2 = PaintDotNet.SystemLayer.Clipboard.Open(currentWindow)) { bool flag = transaction2.TryGetRawNativeData(8, delegate(UnsafeBufferLock buffer) { Size size; byte *pBitmapInfo = (byte *)buffer.Address; int ncbBitmapInfo = (int)buffer.Size; if (PdnGraphics.TryGetBitmapInfoSize(pBitmapInfo, ncbBitmapInfo, out size)) { surface = new Surface(size.Width, size.Height); bool flag = false; try { using (Bitmap bitmap = surface.CreateAliasedBitmap(true)) { flag = PdnGraphics.TryCopyFromBitmapInfo(bitmap, pBitmapInfo, ncbBitmapInfo); } surface.DetectAndFixDishonestAlpha(); } finally { if ((surface != null) && !flag) { surface.Dispose(); surface = null; } } } }); } } catch (OutOfMemoryException) { throw; } catch (Exception) { } } if (((image == null) && (surface == null)) && (clipData.GetDataPresent(PdnDataObjectFormats.Bitmap, true) || clipData.GetDataPresent(PdnDataObjectFormats.EnhancedMetafile, true))) { try { image = clipData.GetData(PdnDataObjectFormats.Bitmap, true) as Image; } catch (OutOfMemoryException) { throw; } catch (Exception) { } if (image == null) { try { using (PaintDotNet.SystemLayer.Clipboard.Transaction transaction3 = PaintDotNet.SystemLayer.Clipboard.Open(currentWindow)) { image = transaction3.TryGetEmf(); Image image1 = image; } } catch (OutOfMemoryException) { throw; } catch (Exception) { } } } if (((image == null) && (surface == null)) && clipData.GetDataPresent("PNG", false)) { try { bool flag2 = false; using (PaintDotNet.SystemLayer.Clipboard.Transaction transaction4 = PaintDotNet.SystemLayer.Clipboard.Open(currentWindow)) { uint formatID = PaintDotNet.SystemLayer.Clipboard.RegisterFormat("PNG"); flag2 = transaction4.TryGetRawNativeData(formatID, delegate(Stream stream) { image = Image.FromStream(stream, false, true); }); } if (flag2 && (image != null)) { surface = Surface.CopyFromGdipImage(image, false); DisposableUtil.Free <Image>(ref image); } } catch (OutOfMemoryException) { throw; } catch (Exception) { } } if ((surface != null) && (image != null)) { throw new InternalErrorException("both surface and image are non-null"); } if ((surface == null) && (image != null)) { surface = Surface.CopyFromGdipImage(image, true); } return(surface); }
/// <summary> /// Takes a Surface and quantizes it down to an 8-bit bitmap. /// </summary> /// <param name="quantizeMe">The Surface to quantize.</param> /// <param name="ditherAmount">How strong should dithering be applied. 0 for no dithering, 8 for full dithering. 7 is generally a good default to use.</param> /// <param name="maxColors">The maximum number of colors to use. This may range from 2 to 256.</param> /// <param name="enableTransparency">If true, then one color slot will be reserved for transparency. Any color with an alpha value less than 255 will be transparent in the output.</param> /// <param name="progressCallback">The progress callback delegate.</param> /// <returns>An 8-bit Bitmap that is the same size as quantizeMe.</returns> protected Bitmap Quantize(Surface quantizeMe, int ditherAmount, int maxColors, bool enableTransparency, ProgressEventHandler progressCallback) { if (ditherAmount < 0 || ditherAmount > 8) { throw new ArgumentOutOfRangeException( "ditherAmount", ditherAmount, "Out of bounds. Must be in the range [0, 8]"); } if (maxColors < 2 || maxColors > 256) { throw new ArgumentOutOfRangeException( "maxColors", maxColors, "Out of bounds. Must be in the range [2, 256]"); } // TODO: detect if transparency is needed? or take another argument using (Bitmap bitmap = quantizeMe.CreateAliasedBitmap(quantizeMe.Bounds, true)) { OctreeQuantizer quantizer = new OctreeQuantizer(maxColors, enableTransparency); quantizer.DitherLevel = ditherAmount; Bitmap quantized = quantizer.Quantize(bitmap, progressCallback); return quantized; } }