public static extern FIBITMAP Composite(FIBITMAP fg, bool useFileBkg, [In, MarshalAs(UnmanagedType.LPStruct)] RGBQUAD appBkColor, FIBITMAP bg);
private FI.FIBITMAP _encode( Stream input, CodecData codecData ) { var ret = new FI.FIBITMAP(); ret.SetNull(); var imgData = codecData as ImageData; if ( imgData != null ) { var data = new byte[(int)input.Length]; input.Read( data, 0, data.Length ); var dataPtr = BufferBase.Wrap( data ); var src = new PixelBox( imgData.width, imgData.height, imgData.depth, imgData.format, dataPtr ); // The required format, which will adjust to the format // actually supported by FreeImage. var requiredFormat = imgData.format; // determine the settings var imageType = FI.FREE_IMAGE_TYPE.FIT_UNKNOWN; var determiningFormat = imgData.format; switch ( determiningFormat ) { case PixelFormat.R5G6B5: case PixelFormat.B5G6R5: case PixelFormat.R8G8B8: case PixelFormat.B8G8R8: case PixelFormat.A8R8G8B8: case PixelFormat.X8R8G8B8: case PixelFormat.A8B8G8R8: case PixelFormat.X8B8G8R8: case PixelFormat.B8G8R8A8: case PixelFormat.R8G8B8A8: case PixelFormat.A4L4: case PixelFormat.BYTE_LA: case PixelFormat.R3G3B2: case PixelFormat.A4R4G4B4: case PixelFormat.A1R5G5B5: case PixelFormat.A2R10G10B10: case PixelFormat.A2B10G10R10: // I'd like to be able to use r/g/b masks to get FreeImage to load the data // in it's existing format, but that doesn't work, FreeImage needs to have // data in RGB[A] (big endian) and BGR[A] (little endian), always. if ( PixelUtil.HasAlpha( determiningFormat ) ) { if ( FI.FreeImageEngine.IsLittleEndian ) { requiredFormat = PixelFormat.BYTE_BGRA; } else { requiredFormat = PixelFormat.BYTE_RGBA; } } else { if ( FI.FreeImageEngine.IsLittleEndian ) { requiredFormat = PixelFormat.BYTE_BGR; } else { requiredFormat = PixelFormat.BYTE_RGB; } } imageType = FI.FREE_IMAGE_TYPE.FIT_BITMAP; break; case PixelFormat.L8: case PixelFormat.A8: imageType = FI.FREE_IMAGE_TYPE.FIT_BITMAP; break; case PixelFormat.L16: imageType = FI.FREE_IMAGE_TYPE.FIT_UINT16; break; case PixelFormat.SHORT_GR: requiredFormat = PixelFormat.SHORT_RGB; break; case PixelFormat.SHORT_RGB: imageType = FI.FREE_IMAGE_TYPE.FIT_RGB16; break; case PixelFormat.SHORT_RGBA: imageType = FI.FREE_IMAGE_TYPE.FIT_RGBA16; break; case PixelFormat.FLOAT16_R: requiredFormat = PixelFormat.FLOAT32_R; break; case PixelFormat.FLOAT32_R: imageType = FI.FREE_IMAGE_TYPE.FIT_FLOAT; break; case PixelFormat.FLOAT16_GR: case PixelFormat.FLOAT16_RGB: case PixelFormat.FLOAT32_GR: requiredFormat = PixelFormat.FLOAT32_RGB; break; case PixelFormat.FLOAT32_RGB: imageType = FI.FREE_IMAGE_TYPE.FIT_RGBF; break; case PixelFormat.FLOAT16_RGBA: requiredFormat = PixelFormat.FLOAT32_RGBA; break; case PixelFormat.FLOAT32_RGBA: imageType = FI.FREE_IMAGE_TYPE.FIT_RGBAF; break; default: throw new AxiomException( "Not Supported image format :{0}", determiningFormat.ToString() ); } //end switch // Check support for this image type & bit depth if ( !FI.FreeImage.FIFSupportsExportType( (FI.FREE_IMAGE_FORMAT)this._freeImageType, imageType ) || !FI.FreeImage.FIFSupportsExportBPP( (FI.FREE_IMAGE_FORMAT)this._freeImageType, PixelUtil.GetNumElemBits( requiredFormat ) ) ) { // Ok, need to allocate a fallback // Only deal with RGBA . RGB for now switch ( requiredFormat ) { case PixelFormat.BYTE_RGBA: requiredFormat = PixelFormat.BYTE_RGB; break; case PixelFormat.BYTE_BGRA: requiredFormat = PixelFormat.BYTE_BGR; break; default: break; } } var conversionRequired = false; input.Position = 0; var srcData = new byte[ (int)input.Length ]; input.Read( srcData, 0, srcData.Length ); var srcDataPtr = BufferBase.Wrap( srcData ); // Check BPP var bpp = PixelUtil.GetNumElemBits( requiredFormat ); if ( !FI.FreeImage.FIFSupportsExportBPP( (FI.FREE_IMAGE_FORMAT)this._freeImageType, bpp ) ) { if ( bpp == 32 && PixelUtil.HasAlpha( imgData.format ) && FI.FreeImage.FIFSupportsExportBPP( (FI.FREE_IMAGE_FORMAT)this._freeImageType, 24 ) ) { // drop to 24 bit (lose alpha) if ( FI.FreeImage.IsLittleEndian() ) { requiredFormat = PixelFormat.BYTE_BGR; } else { requiredFormat = PixelFormat.BYTE_RGB; } bpp = 24; } else if ( bpp == 128 && PixelUtil.HasAlpha( imgData.format ) && FI.FreeImage.FIFSupportsExportBPP( (FI.FREE_IMAGE_FORMAT)this._freeImageType, 96 ) ) { // drop to 96-bit floating point requiredFormat = PixelFormat.FLOAT32_RGB; } } var convBox = new PixelBox( imgData.width, imgData.height, 1, requiredFormat ); if ( requiredFormat != imgData.format ) { conversionRequired = true; // Allocate memory var convData = new byte[convBox.ConsecutiveSize]; convBox.Data = BufferBase.Wrap( convData ); // perform conversion and reassign source var newSrc = new PixelBox( imgData.width, imgData.height, 1, imgData.format, dataPtr ); PixelConverter.BulkPixelConversion( newSrc, convBox ); srcDataPtr = convBox.Data; } ret = FI.FreeImage.AllocateT( imageType, imgData.width, imgData.height, bpp ); if ( ret.IsNull ) { if ( conversionRequired ) { srcDataPtr.SafeDispose(); convBox = null; } throw new AxiomException( "FreeImage.AllocateT failed - possibly out of memory. " ); } if ( requiredFormat == PixelFormat.L8 || requiredFormat == PixelFormat.A8 ) { // Must explicitly tell FreeImage that this is greyscale by setting // a "grey" palette (otherwise it will save as a normal RGB // palettized image). var tmp = FI.FreeImage.ConvertToGreyscale( ret ); FI.FreeImage.Unload( ret ); ret = tmp; } var dstPitch = (int)FI.FreeImage.GetPitch( ret ); var srcPitch = imgData.width*PixelUtil.GetNumElemBytes( requiredFormat ); // Copy data, invert scanlines and respect FreeImage pitch var pSrc = srcDataPtr; using ( var pDest = BufferBase.Wrap( FI.FreeImage.GetBits( ret ), imgData.height * srcPitch ) ) { var byteSrcData = pSrc; var byteDstData = pDest; for ( var y = 0; y < imgData.height; ++y ) { byteSrcData += ( imgData.height - y - 1 ) * srcPitch; Memory.Copy( pSrc, pDest, srcPitch ); byteDstData += dstPitch; } } if ( conversionRequired ) { // delete temporary conversion area srcDataPtr.SafeDispose(); convBox = null; } } return ret; }
public static extern bool GetHistogram(FIBITMAP dib, IntPtr histo, FREE_IMAGE_COLOR_CHANNEL channel);
public static extern FIBITMAP Copy(FIBITMAP dib, int left, int top, int right, int bottom);
public static extern bool AdjustGamma(FIBITMAP dib, double gamma);
public static extern bool AdjustContrast(FIBITMAP dib, double percentage);
public static extern void ConvertToRawBits(IntPtr bits, FIBITMAP dib, int pitch, uint bpp, uint redMask, uint greenMask, uint blueMask, bool topDown);
public static extern FIBITMAP Rescale(FIBITMAP dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
public static extern FIBITMAP Threshold(FIBITMAP dib, uint T);
public static extern FIBITMAP Dither(FIBITMAP dib, FREE_IMAGE_DITHER algorithm);
public static extern FIBITMAP ColorQuantize(FIBITMAP dib, FREE_IMAGE_QUANTIZE quantize);
public static extern FIBITMAP ConvertTo32Bits(FIBITMAP dib);
public static extern FIBITMAP ConvertTo16Bits565(FIBITMAP dib);
public static extern bool SetBackgroundColor(FIBITMAP dib, [In, MarshalAs(UnmanagedType.LPStruct)] RGBQUAD bkcolor);
public static extern FIBITMAP ConvertToType(FIBITMAP dib, FREE_IMAGE_TYPE dst_type, bool scale_linear);
public static extern bool FlipVertical(FIBITMAP dib);
public static extern FIBITMAP ConvertToRGBF(FIBITMAP dib);
public static extern bool AdjustCurve(FIBITMAP dib, byte[] lut, FREE_IMAGE_COLOR_CHANNEL channel);
public static extern FIBITMAP ToneMapping(FIBITMAP dib, FREE_IMAGE_TMO tmo, double first_param, double second_param);
public static extern bool AdjustBrightness(FIBITMAP dib, double percentage);
public static extern FIBITMAP TmoDrago03(FIBITMAP dib, double gamma, double exposure);
public static extern bool Invert(FIBITMAP dib);
public static extern FIBITMAP TmoReinhard05(FIBITMAP dib, double intensity, double contrast);
public static extern bool SetChannel(FIBITMAP dib, FIBITMAP dib8, FREE_IMAGE_COLOR_CHANNEL channel);
public static extern FIBITMAP RotateClassic(FIBITMAP dib, double angle);
public static extern bool Paste(FIBITMAP dst, FIBITMAP src, int left, int top, int alpha);
public static extern FIBITMAP RotateEx( FIBITMAP dib, double angle, double xShift, double yShift, double xOrigin, double yOrigin, bool useMask);
/// <summary> /// Creates a new ICC-Profile for <paramref name="dib"/>. /// </summary> /// <param name="dib">Handle to a FreeImage bitmap.</param> /// <param name="data">The ICC-Profile data.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="dib"/> is null.</exception> public FIICCPROFILE(FIBITMAP dib, byte[] data) : this(dib, data, (int)data.Length) { }
public static extern bool FlipHorizontal(FIBITMAP dib);
private FI.FIBITMAP _encode(Stream input, CodecData codecData) { var ret = new FI.FIBITMAP(); ret.SetNull(); var imgData = codecData as ImageData; if (imgData != null) { var data = new byte[(int)input.Length]; input.Read(data, 0, data.Length); var dataPtr = BufferBase.Wrap(data); var src = new PixelBox(imgData.width, imgData.height, imgData.depth, imgData.format, dataPtr); // The required format, which will adjust to the format // actually supported by FreeImage. var requiredFormat = imgData.format; // determine the settings var imageType = FI.FREE_IMAGE_TYPE.FIT_UNKNOWN; var determiningFormat = imgData.format; switch (determiningFormat) { case PixelFormat.R5G6B5: case PixelFormat.B5G6R5: case PixelFormat.R8G8B8: case PixelFormat.B8G8R8: case PixelFormat.A8R8G8B8: case PixelFormat.X8R8G8B8: case PixelFormat.A8B8G8R8: case PixelFormat.X8B8G8R8: case PixelFormat.B8G8R8A8: case PixelFormat.R8G8B8A8: case PixelFormat.A4L4: case PixelFormat.BYTE_LA: case PixelFormat.R3G3B2: case PixelFormat.A4R4G4B4: case PixelFormat.A1R5G5B5: case PixelFormat.A2R10G10B10: case PixelFormat.A2B10G10R10: // I'd like to be able to use r/g/b masks to get FreeImage to load the data // in it's existing format, but that doesn't work, FreeImage needs to have // data in RGB[A] (big endian) and BGR[A] (little endian), always. if (PixelUtil.HasAlpha(determiningFormat)) { if (FI.FreeImageEngine.IsLittleEndian) { requiredFormat = PixelFormat.BYTE_BGRA; } else { requiredFormat = PixelFormat.BYTE_RGBA; } } else { if (FI.FreeImageEngine.IsLittleEndian) { requiredFormat = PixelFormat.BYTE_BGR; } else { requiredFormat = PixelFormat.BYTE_RGB; } } imageType = FI.FREE_IMAGE_TYPE.FIT_BITMAP; break; case PixelFormat.L8: case PixelFormat.A8: imageType = FI.FREE_IMAGE_TYPE.FIT_BITMAP; break; case PixelFormat.L16: imageType = FI.FREE_IMAGE_TYPE.FIT_UINT16; break; case PixelFormat.SHORT_GR: requiredFormat = PixelFormat.SHORT_RGB; break; case PixelFormat.SHORT_RGB: imageType = FI.FREE_IMAGE_TYPE.FIT_RGB16; break; case PixelFormat.SHORT_RGBA: imageType = FI.FREE_IMAGE_TYPE.FIT_RGBA16; break; case PixelFormat.FLOAT16_R: requiredFormat = PixelFormat.FLOAT32_R; break; case PixelFormat.FLOAT32_R: imageType = FI.FREE_IMAGE_TYPE.FIT_FLOAT; break; case PixelFormat.FLOAT16_GR: case PixelFormat.FLOAT16_RGB: case PixelFormat.FLOAT32_GR: requiredFormat = PixelFormat.FLOAT32_RGB; break; case PixelFormat.FLOAT32_RGB: imageType = FI.FREE_IMAGE_TYPE.FIT_RGBF; break; case PixelFormat.FLOAT16_RGBA: requiredFormat = PixelFormat.FLOAT32_RGBA; break; case PixelFormat.FLOAT32_RGBA: imageType = FI.FREE_IMAGE_TYPE.FIT_RGBAF; break; default: throw new AxiomException("Not Supported image format :{0}", determiningFormat.ToString()); } //end switch // Check support for this image type & bit depth if (!FI.FreeImage.FIFSupportsExportType((FI.FREE_IMAGE_FORMAT) this._freeImageType, imageType) || !FI.FreeImage.FIFSupportsExportBPP((FI.FREE_IMAGE_FORMAT) this._freeImageType, PixelUtil.GetNumElemBits(requiredFormat))) { // Ok, need to allocate a fallback // Only deal with RGBA . RGB for now switch (requiredFormat) { case PixelFormat.BYTE_RGBA: requiredFormat = PixelFormat.BYTE_RGB; break; case PixelFormat.BYTE_BGRA: requiredFormat = PixelFormat.BYTE_BGR; break; default: break; } } var conversionRequired = false; input.Position = 0; var srcData = new byte[(int)input.Length]; input.Read(srcData, 0, srcData.Length); var srcDataPtr = BufferBase.Wrap(srcData); // Check BPP var bpp = PixelUtil.GetNumElemBits(requiredFormat); if (!FI.FreeImage.FIFSupportsExportBPP((FI.FREE_IMAGE_FORMAT) this._freeImageType, bpp)) { if (bpp == 32 && PixelUtil.HasAlpha(imgData.format) && FI.FreeImage.FIFSupportsExportBPP((FI.FREE_IMAGE_FORMAT) this._freeImageType, 24)) { // drop to 24 bit (lose alpha) if (FI.FreeImage.IsLittleEndian()) { requiredFormat = PixelFormat.BYTE_BGR; } else { requiredFormat = PixelFormat.BYTE_RGB; } bpp = 24; } else if (bpp == 128 && PixelUtil.HasAlpha(imgData.format) && FI.FreeImage.FIFSupportsExportBPP((FI.FREE_IMAGE_FORMAT) this._freeImageType, 96)) { // drop to 96-bit floating point requiredFormat = PixelFormat.FLOAT32_RGB; } } var convBox = new PixelBox(imgData.width, imgData.height, 1, requiredFormat); if (requiredFormat != imgData.format) { conversionRequired = true; // Allocate memory var convData = new byte[convBox.ConsecutiveSize]; convBox.Data = BufferBase.Wrap(convData); // perform conversion and reassign source var newSrc = new PixelBox(imgData.width, imgData.height, 1, imgData.format, dataPtr); PixelConverter.BulkPixelConversion(newSrc, convBox); srcDataPtr = convBox.Data; } ret = FI.FreeImage.AllocateT(imageType, imgData.width, imgData.height, bpp); if (ret.IsNull) { if (conversionRequired) { srcDataPtr.SafeDispose(); convBox = null; } throw new AxiomException("FreeImage.AllocateT failed - possibly out of memory. "); } if (requiredFormat == PixelFormat.L8 || requiredFormat == PixelFormat.A8) { // Must explicitly tell FreeImage that this is greyscale by setting // a "grey" palette (otherwise it will save as a normal RGB // palettized image). var tmp = FI.FreeImage.ConvertToGreyscale(ret); FI.FreeImage.Unload(ret); ret = tmp; } var dstPitch = (int)FI.FreeImage.GetPitch(ret); var srcPitch = imgData.width * PixelUtil.GetNumElemBytes(requiredFormat); // Copy data, invert scanlines and respect FreeImage pitch var pSrc = srcDataPtr; using (var pDest = BufferBase.Wrap(FI.FreeImage.GetBits(ret), imgData.height * srcPitch)) { var byteSrcData = pSrc; var byteDstData = pDest; for (var y = 0; y < imgData.height; ++y) { byteSrcData += (imgData.height - y - 1) * srcPitch; Memory.Copy(pSrc, pDest, srcPitch); byteDstData += dstPitch; } } if (conversionRequired) { // delete temporary conversion area srcDataPtr.SafeDispose(); convBox = null; } } return(ret); }
public static extern bool HasBackgroundColor(FIBITMAP dib);