//------------------------------------------------------------------------------------- // Encodes a single frame //------------------------------------------------------------------------------------- private static void EncodeImage(PixelBuffer image, WICFlags flags, WIC.BitmapFrameEncode frame) { Guid pfGuid; if (!ToWIC(image.Format, out pfGuid)) { throw new NotSupportedException("Format not supported"); } frame.Initialize(); frame.SetSize(image.Width, image.Height); frame.SetResolution(72, 72); Guid targetGuid = pfGuid; frame.SetPixelFormat(ref targetGuid); if (targetGuid != pfGuid) { using (var source = new WIC.Bitmap(Factory, image.Width, image.Height, pfGuid, new SDX.DataRectangle(image.DataPointer, image.RowStride), image.BufferStride)) { using (var converter = new WIC.FormatConverter(Factory)) { using (var palette = new WIC.Palette(Factory)) { palette.Initialize(source, 256, true); converter.Initialize(source, targetGuid, GetWICDither(flags), palette, 0, WIC.BitmapPaletteType.Custom); int bpp = GetBitsPerPixel(targetGuid); if (bpp == 0) { throw new NotSupportedException("Unable to determine the Bpp for the target format"); } int rowPitch = (image.Width * bpp + 7) / 8; int slicePitch = rowPitch * image.Height; var temp = SDX.Utilities.AllocateMemory(slicePitch); try { converter.CopyPixels(rowPitch, temp, slicePitch); frame.Palette = palette; frame.WritePixels(image.Height, temp, rowPitch, slicePitch); } finally { SDX.Utilities.FreeMemory(temp); } } } } } else { // No conversion required frame.WritePixels(image.Height, image.DataPointer, image.RowStride, image.BufferStride); } frame.Commit(); }
//------------------------------------------------------------------------------------- // Encodes a single frame //------------------------------------------------------------------------------------- private static void EncodeImage( PixelBuffer image, WICFlags flags, BitmapFrameEncode frame) { Guid pfGuid; if (! ToWIC(image.Format, out pfGuid)) throw new NotSupportedException("Format not supported"); frame.Initialize(); frame.SetSize(image.Width, image.Height); frame.SetResolution(72, 72); Guid targetGuid = pfGuid; frame.SetPixelFormat(ref targetGuid); if (targetGuid != pfGuid) { using (var source = new Bitmap(Factory, image.Width, image.Height, pfGuid, new DataRectangle(image.DataPointer, image.RowStride), image.BufferStride)) { using (var converter = new FormatConverter(Factory)) { using (var palette = new Palette(Factory)) { palette.Initialize(source, 256, true); converter.Initialize(source, targetGuid, GetWICDither(flags), palette, 0, BitmapPaletteType.Custom); int bpp = GetBitsPerPixel(targetGuid); if (bpp == 0) throw new NotSupportedException("Unable to determine the Bpp for the target format"); int rowPitch = (image.Width * bpp + 7) / 8; int slicePitch = rowPitch * image.Height; var temp = Utilities.AllocateMemory(slicePitch); try { converter.CopyPixels(rowPitch, temp, slicePitch); frame.Palette = palette; frame.WritePixels(image.Height, temp, rowPitch, slicePitch); } finally { Utilities.FreeMemory(temp); } } } } } else { // No conversion required frame.WritePixels(image.Height, image.DataPointer, image.RowStride, image.BufferStride); } frame.Commit(); }
/// <summary> /// Function to convert the format of a bitmap into the format of the buffer. /// </summary> /// <param name="sourceFormat">Format to convert from.</param> /// <param name="destFormat">Format to convert into.</param> /// <param name="dithering">Dithering to apply.</param> /// <param name="filter">Filtering to apply to scaled bitmaps.</param> /// <param name="bitmap">Bitmap to convert.</param> /// <param name="bitmapPalette">Palette for the bitmap.</param> /// <param name="alphaValue">Value of pixel to consider transparent.</param> /// <param name="buffer">Buffer holding the converted data.</param> /// <param name="scale">TRUE to scale when converting, FALSE to keep at original size.</param> /// <param name="clip">TRUE to perform clipping, FALSE to keep at original size.</param> private void ConvertFormat(Guid sourceFormat, Guid destFormat, WIC.BitmapDitherType dithering, WIC.BitmapInterpolationMode filter, WIC.BitmapSource bitmap, WIC.Palette bitmapPalette, int alphaValue, GorgonImageBuffer buffer, bool scale, bool clip) { WIC.BitmapSource source = bitmap; double alphaPercent = alphaValue / 255.0; var paletteType = WIC.BitmapPaletteType.Custom; // If we have a palette, then confirm that the dithering method is valid. if (bitmapPalette != null) { // Do not apply dithering if we're using // a custom palette and request ordered dithering. switch (dithering) { case WIC.BitmapDitherType.Ordered4x4: case WIC.BitmapDitherType.Ordered8x8: case WIC.BitmapDitherType.Ordered16x16: if (bitmapPalette.TypeInfo == WIC.BitmapPaletteType.Custom) { dithering = WIC.BitmapDitherType.None; } break; } paletteType = bitmapPalette.TypeInfo; } try { // Create a scaler if need one. if ((scale) && (!clip)) { var scaler = new WIC.BitmapScaler(Factory); scaler.Initialize(bitmap, buffer.Width, buffer.Height, filter); source = scaler; } // Create a clipper if we want to clip and the image needs resizing. if ((clip) && (scale) && ((buffer.Width < bitmap.Size.Width) || (buffer.Height < bitmap.Size.Height))) { var clipper = new WIC.BitmapClipper(Factory); clipper.Initialize(bitmap, new DX.Rectangle(0, 0, buffer.Width < bitmap.Size.Width ? buffer.Width : bitmap.Size.Width, buffer.Height < bitmap.Size.Height ? buffer.Height : bitmap.Size.Height)); source = clipper; } using (var converter = new WIC.FormatConverter(Factory)) { if (!converter.CanConvert(sourceFormat, destFormat)) { throw new GorgonException(GorgonResult.FormatNotSupported, string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, buffer.Format)); } converter.Initialize(source, destFormat, dithering, bitmapPalette, alphaPercent, paletteType); if (!scale) { int rowPitch = (GetBitsPerPixel(destFormat) * bitmap.Size.Width + 7) / 8; int slicePitch = rowPitch * bitmap.Size.Height; if ((rowPitch != buffer.PitchInformation.RowPitch) || (slicePitch != buffer.PitchInformation.SlicePitch)) { throw new GorgonException(GorgonResult.CannotWrite, Resources.GORGFX_IMAGE_PITCH_TOO_SMALL); } } converter.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch); } } finally { if (source != bitmap) { source.Dispose(); } } }