using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Runtime.InteropServices; using System.Drawing; using System.Drawing.Imaging; namespace LibwebpSharp { /// /// /// public class WebPDecoder { private enum decodeType { RGB, RGBA, BGR, BGRA, YUV }; /// /// The decoder's version number /// /// The version as major.minor.revision public string GetDecoderVersion() { int version = Native.WebPDecoder.WebPGetDecoderVersion(); return String.Format("{0}.{1}.{2}", (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); } /// /// Validate the WebP image header and retrieve the image height and width /// /// The path to the WebP image file /// Returns the width of the WebP image /// Returnsthe height of the WebP image /// True if the WebP image header is valid, otherwise false public bool GetInfo(string path, out int imgWidth, out int imgHeight) { bool retValue = false; int width = 0; int height = 0; IntPtr pnt = IntPtr.Zero; try { byte[] data = Utilities.CopyFileToManagedArray(path); pnt = Utilities.CopyDataToUnmanagedMemory(data); int ret = Native.WebPDecoder.WebPGetInfo(pnt, (uint)data.Length, ref width, ref height); if (ret == 1) { retValue = true; } } catch { throw; } finally { // Free the unmanaged memory. Marshal.FreeHGlobal(pnt); } imgWidth = width; imgHeight = height; return retValue; } /// /// Decode the WebP image into a RGB Bitmap /// /// The path to the WebP image file /// A Bitmap object with the decoded WebP image. /// Note that a Bitmap object use the BGR format, so if you display the Bitmap in a picturebox red and blue are mixed up public Bitmap DecodeRGB(string path) { return decode(path, decodeType.RGB, PixelFormat.Format24bppRgb); } /// /// Decode the WebP image into a RGBA Bitmap /// /// The path to the WebP image file /// A Bitmap object with the decoded WebP image. /// Note that a Bitmap object use the ABGR format, so if you display the Bitmap in a picturebox red and blue are mixed up public Bitmap DecodeRGBA(string path) { return decode(path, decodeType.RGBA, PixelFormat.Format32bppArgb); } /// /// Decode the WebP image into a BGR Bitmap /// /// The path to the WebP image file /// A Bitmap object with the decoded WebP image public Bitmap DecodeBGR(string path) { return decode(path, decodeType.BGR, PixelFormat.Format24bppRgb); } /// /// Decode the WebP image into a BGRA Bitmap /// /// The path to the WebP image file /// A Bitmap object with the decoded WebP image public Bitmap DecodeBGRA(string path) { return decode(path, decodeType.BGRA, PixelFormat.Format32bppArgb); } /// /// Decode the WebP image into a BGRA Bitmap /// /// The path to the WebP image file /// A Bitmap object with the decoded WebP image public Bitmap DecodeBGRA(Stream fs) { byte[] data = new byte[fs.Length]; fs.Read(data, 0, (int)fs.Length); fs.Close(); return decode(data, decodeType.BGRA, PixelFormat.Format32bppArgb); } /// /// Decode the WebP image file into raw RGB image data /// /// The path to the WebP image file /// Returns the width of the WebP image /// Returns the height of the WebP image /// A byte array containing the raw decoded image data public byte[] DecodeRGB(string path, out int imgWidth, out int imgHeight) { return decode(path, decodeType.RGB, PixelFormat.Format24bppRgb, out imgWidth, out imgHeight); } /// /// Decode the WebP image file into raw RGBA image data /// /// The path to the WebP image file /// Returns the width of the WebP image /// Returns the height of the WebP image /// A byte array containing the raw decoded image data public byte[] DecodeRGBA(string path, out int imgWidth, out int imgHeight) { return decode(path, decodeType.RGBA, PixelFormat.Format32bppArgb, out imgWidth, out imgHeight); } /// /// Decode the WebP image file into raw BGR image data /// /// The path to the WebP image file /// Returns the width of the WebP image /// Returns the height of the WebP image /// A byte array containing the raw decoded image data public byte[] DecodeBGR(string path, out int imgWidth, out int imgHeight) { return decode(path, decodeType.BGR, PixelFormat.Format24bppRgb, out imgWidth, out imgHeight); } /// /// Decode the WebP image file into raw BGRA image data /// /// The path to the WebP image file /// Returns the width of the WebP image /// Returns the height of the WebP image /// A byte array containing the raw decoded image data public byte[] DecodeBGRA(string path, out int imgWidth, out int imgHeight) { return decode(path, decodeType.BGRA, PixelFormat.Format32bppArgb, out imgWidth, out imgHeight); } /// /// Internal convert method to get a Bitmap from a WebP image file /// /// The path to the WebP image file /// The color type you want to convert to /// The PixelFormat the Bitmap should use /// private Bitmap decode(string path, decodeType type, PixelFormat format) { int width = 0; int height = 0; byte[] data = decode(path, type, format, out width, out height); return Utilities.ConvertDataToBitmap(data, width, height, format); } /// /// Internal convert method to get a Bitmap from a WebP image file /// /// webp文件数据 /// The color type you want to convert to /// The PixelFormat the Bitmap should use /// private Bitmap decode(byte[] fs_data, decodeType type, PixelFormat format) { byte[] data = decode(fs_data, type, format, out int width, out int height); return Utilities.ConvertDataToBitmap(data, width, height, format); } /// /// Internal convert method to get a byte array from a WebP image file /// /// The path to the WebP image file /// The color type you want to convert to /// The PixelFormat you want to use /// Returns the width of the WebP image /// Returns the height of the WebP image /// private byte[] decode(string path, decodeType type, PixelFormat format, out int imgWidth, out int imgHeight) { return decode(Utilities.CopyFileToManagedArray(path), type, format,out imgWidth,out imgHeight); } /// /// Internal convert method to get a byte array from a WebP image file /// /// The path to the WebP image file /// The color type you want to convert to /// The PixelFormat you want to use /// Returns the width of the WebP image /// Returns the height of the WebP image /// private byte[] decode(byte[] managedData, decodeType type, PixelFormat format, out int imgWidth, out int imgHeight) { int width = 0; int height = 0; IntPtr data = IntPtr.Zero; IntPtr output_buffer = IntPtr.Zero; IntPtr result = IntPtr.Zero; try { // Copy data to unmanaged memory data = Utilities.CopyDataToUnmanagedMemory(managedData); // Get image width and height int ret = Native.WebPDecoder.WebPGetInfo(data, (uint)managedData.Length, ref width, ref height); // Get image data lenght UInt32 data_size = (UInt32)managedData.Length; // Calculate bitmap size for decoded WebP image int output_buffer_size = Utilities.CalculateBitmapSize(width, height, format); // Allocate unmanaged memory to decoded WebP image output_buffer = Marshal.AllocHGlobal(output_buffer_size); // Calculate distance between scanlines int output_stride = (width * Image.GetPixelFormatSize(format)) / 8; // Convert image switch (type) { case decodeType.RGB: result = Native.WebPDecoder.WebPDecodeRGBInto(data, data_size, output_buffer, output_buffer_size, output_stride); break; case decodeType.RGBA: result = Native.WebPDecoder.WebPDecodeRGBAInto(data, data_size, output_buffer, output_buffer_size, output_stride); break; case decodeType.BGR: result = Native.WebPDecoder.WebPDecodeBGRInto(data, data_size, output_buffer, output_buffer_size, output_stride); break; case decodeType.BGRA: result = Native.WebPDecoder.WebPDecodeBGRAInto(data, data_size, output_buffer, output_buffer_size, output_stride); break; } // Set out values imgWidth = width; imgHeight = height; // Copy data back to managed memory and return return Utilities.GetDataFromUnmanagedMemory(result, output_buffer_size); } catch { throw; } finally { // Free unmanaged memory Marshal.FreeHGlobal(data); Marshal.FreeHGlobal(output_buffer); } } } }