RaUI/Source/MyDb/WebP/WebPDecoder.cs
鑫Intel a1d6dce946 ### 2021-08-03更新
------
#### MyDbV4    V3.0.2108.0301
- *.[新增]新增内置HtmlAgilityPack组件。
2021-08-30 19:47:56 +08:00

288 lines
12 KiB
C#

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
{
/// <summary>
///
/// </summary>
public class WebPDecoder
{
private enum decodeType
{
RGB,
RGBA,
BGR,
BGRA,
YUV
};
/// <summary>
/// The decoder's version number
/// </summary>
/// <returns>The version as major.minor.revision</returns>
public string GetDecoderVersion()
{
int version = Native.WebPDecoder.WebPGetDecoderVersion();
return String.Format("{0}.{1}.{2}", (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
}
/// <summary>
/// Validate the WebP image header and retrieve the image height and width
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <param name="imgWidth">Returns the width of the WebP image</param>
/// <param name="imgHeight">Returnsthe height of the WebP image</param>
/// <returns>True if the WebP image header is valid, otherwise false</returns>
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;
}
/// <summary>
/// Decode the WebP image into a RGB Bitmap
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <returns>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</returns>
public Bitmap DecodeRGB(string path)
{
return decode(path, decodeType.RGB, PixelFormat.Format24bppRgb);
}
/// <summary>
/// Decode the WebP image into a RGBA Bitmap
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <returns>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</returns>
public Bitmap DecodeRGBA(string path)
{
return decode(path, decodeType.RGBA, PixelFormat.Format32bppArgb);
}
/// <summary>
/// Decode the WebP image into a BGR Bitmap
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <returns>A Bitmap object with the decoded WebP image</returns>
public Bitmap DecodeBGR(string path)
{
return decode(path, decodeType.BGR, PixelFormat.Format24bppRgb);
}
/// <summary>
/// Decode the WebP image into a BGRA Bitmap
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <returns>A Bitmap object with the decoded WebP image</returns>
public Bitmap DecodeBGRA(string path)
{
return decode(path, decodeType.BGRA, PixelFormat.Format32bppArgb);
}
/// <summary>
/// Decode the WebP image into a BGRA Bitmap
/// </summary>
/// <param name="fs">The path to the WebP image file</param>
/// <returns>A Bitmap object with the decoded WebP image</returns>
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);
}
/// <summary>
/// Decode the WebP image file into raw RGB image data
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <param name="imgWidth">Returns the width of the WebP image</param>
/// <param name="imgHeight">Returns the height of the WebP image</param>
/// <returns>A byte array containing the raw decoded image data</returns>
public byte[] DecodeRGB(string path, out int imgWidth, out int imgHeight)
{
return decode(path, decodeType.RGB, PixelFormat.Format24bppRgb, out imgWidth, out imgHeight);
}
/// <summary>
/// Decode the WebP image file into raw RGBA image data
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <param name="imgWidth">Returns the width of the WebP image</param>
/// <param name="imgHeight">Returns the height of the WebP image</param>
/// <returns>A byte array containing the raw decoded image data</returns>
public byte[] DecodeRGBA(string path, out int imgWidth, out int imgHeight)
{
return decode(path, decodeType.RGBA, PixelFormat.Format32bppArgb, out imgWidth, out imgHeight);
}
/// <summary>
/// Decode the WebP image file into raw BGR image data
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <param name="imgWidth">Returns the width of the WebP image</param>
/// <param name="imgHeight">Returns the height of the WebP image</param>
/// <returns>A byte array containing the raw decoded image data</returns>
public byte[] DecodeBGR(string path, out int imgWidth, out int imgHeight)
{
return decode(path, decodeType.BGR, PixelFormat.Format24bppRgb, out imgWidth, out imgHeight);
}
/// <summary>
/// Decode the WebP image file into raw BGRA image data
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <param name="imgWidth">Returns the width of the WebP image</param>
/// <param name="imgHeight">Returns the height of the WebP image</param>
/// <returns>A byte array containing the raw decoded image data</returns>
public byte[] DecodeBGRA(string path, out int imgWidth, out int imgHeight)
{
return decode(path, decodeType.BGRA, PixelFormat.Format32bppArgb, out imgWidth, out imgHeight);
}
/// <summary>
/// Internal convert method to get a Bitmap from a WebP image file
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <param name="type">The color type you want to convert to</param>
/// <param name="format">The PixelFormat the Bitmap should use</param>
/// <returns></returns>
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);
}
/// <summary>
/// Internal convert method to get a Bitmap from a WebP image file
/// </summary>
/// <param name="fs_data">webp文件数据</param>
/// <param name="type">The color type you want to convert to</param>
/// <param name="format">The PixelFormat the Bitmap should use</param>
/// <returns></returns>
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);
}
/// <summary>
/// Internal convert method to get a byte array from a WebP image file
/// </summary>
/// <param name="path">The path to the WebP image file</param>
/// <param name="type">The color type you want to convert to</param>
/// <param name="format">The PixelFormat you want to use</param>
/// <param name="imgWidth">Returns the width of the WebP image</param>
/// <param name="imgHeight">Returns the height of the WebP image</param>
/// <returns></returns>
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);
}
/// <summary>
/// Internal convert method to get a byte array from a WebP image file
/// </summary>
/// <param name="managedData">The path to the WebP image file</param>
/// <param name="type">The color type you want to convert to</param>
/// <param name="format">The PixelFormat you want to use</param>
/// <param name="imgWidth">Returns the width of the WebP image</param>
/// <param name="imgHeight">Returns the height of the WebP image</param>
/// <returns></returns>
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);
}
}
}
}