C# 使用libjpeg-turbo解壓圖片的程式碼
阿新 • • 發佈:2019-01-24
1、下載:
2、使用方法:
(1)tjInitDecompress 獲取解壓控制代碼
(2)tjDecompressHeader3 獲取jpg圖片資訊
(3)分配記憶體以便放置圖片
(4)tjDecompress2 解壓圖片
(5)tjDestroy 釋放控制代碼
3 原始碼
<Window x:Class="WpfJpgShow.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfJpgShow" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Image Name="myImg"/> </Grid> </Window>
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfJpgShow { /// <summary> /// MainWindow.xaml 的互動邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Task t = new Task(()=> { int nSize = 0; byte[] buffer = null; { FileStream file = new FileStream("d:\\1.jpg", FileMode.Open); nSize = (int)file.Length; buffer = new byte[nSize]; file.Read(buffer, 0, nSize); file.Close(); } int width = 0; int height = 0; int jpegSubsamp = 0; int jpegColorspace = 0; var t1 = DateTime.Now; var hDec = TestJpgCompress.tjInitDecompress(); IntPtr pBufferPtr = IntPtr.Zero; unsafe { fixed (void* p = &buffer[0]) { pBufferPtr = (IntPtr)p; } } int ret = TestJpgCompress.tjDecompressHeader3(hDec, pBufferPtr, (uint)nSize, out width, out height, out jpegSubsamp, out jpegColorspace); TestJpgCompress.TJPixelFormats tJPixelFormats = TestJpgCompress.TJPixelFormats.TJPF_RGB; if (TestJpgCompress.TJColorSpaces.TJCS_GRAY == (TestJpgCompress.TJColorSpaces)jpegColorspace) { tJPixelFormats = TestJpgCompress.TJPixelFormats.TJPF_GRAY; } else if (TestJpgCompress.TJColorSpaces.TJCS_RGB == (TestJpgCompress.TJColorSpaces)jpegColorspace) { tJPixelFormats = TestJpgCompress.TJPixelFormats.TJPF_RGB; } else if (TestJpgCompress.TJColorSpaces.TJCS_YCbCr == (TestJpgCompress.TJColorSpaces)jpegColorspace) { tJPixelFormats = TestJpgCompress.TJPixelFormats.TJPF_BGR; } int nBmpSize = width * height * TestJpgCompress.PixelSizes[tJPixelFormats]; byte[] pBmpBuf = new byte[nBmpSize]; IntPtr pBmpPtr = IntPtr.Zero; unsafe { fixed (void* p = &pBmpBuf[0]) { pBmpPtr = (IntPtr)p; } } ret = TestJpgCompress.tjDecompress2(hDec, pBufferPtr, nSize, pBmpPtr, width, 0, height, (int)tJPixelFormats, 0); TestJpgCompress.tjDestroy(hDec); var t2 = DateTime.Now; Console.WriteLine("解壓耗時"+(t2 - t1).TotalMilliseconds); PixelFormat pixelFormat = PixelFormats.Rgb24; if (TestJpgCompress.TJPixelFormats.TJPF_GRAY == tJPixelFormats) { pixelFormat = PixelFormats.Gray8; } myImg.Dispatcher.BeginInvoke(new Action(delegate { BitmapSource bitmapSource = BitmapSource.Create(width, height, 96, 96, pixelFormat, null, pBmpBuf, width); myImg.Source = bitmapSource; }) ); }); t.Start(); } } class TestJpgCompress { [DllImport("turbojpeg.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr tjInitDecompress(); [DllImport("turbojpeg.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int tjDecompressHeader3(IntPtr handle, IntPtr jpegBuf, uint jpegSize, out int width, out int height, out int jpegSubsamp, out int jpegColorspace); [DllImport("turbojpeg.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int tjDecompress2(IntPtr handle, IntPtr jpegBuf, int jpegSize, IntPtr dstBuf, int width, int pitch, int height, int pixelFormat, int flags); [DllImport("turbojpeg.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int tjDestroy(IntPtr handle); [DllImport("turbojpeg.dll", CallingConvention = CallingConvention.Cdecl)] public static extern uint tjBufSize(int width, int height, int jpegSubsamp); public enum TJColorSpaces { TJCS_RGB = 0, TJCS_YCbCr, TJCS_GRAY, TJCS_CMYK, TJCS_YCCK }; public enum TJSubsamplingOptions { TJSAMP_444 = 0, TJSAMP_422, TJSAMP_420, TJSAMP_GRAY, TJSAMP_440, TJSAMP_411 }; public enum TJPixelFormats { TJPF_RGB = 0, TJPF_BGR, TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB, TJPF_GRAY, TJPF_RGBA, TJPF_BGRA, TJPF_ABGR, TJPF_ARGB, TJPF_CMYK }; [Flags] public enum TJFlags { NONE = 0, BOTTOMUP = 2, FASTUPSAMPLE = 256, NOREALLOC = 1024, FASTDCT = 2048, ACCURATEDCT = 4096 } public enum TJTransformOperations { TJXOP_NONE = 0, TJXOP_HFLIP, TJXOP_VFLIP, TJXOP_TRANSPOSE, TJXOP_TRANSVERSE, TJXOP_ROT90, TJXOP_ROT180, TJXOP_ROT270 }; [Flags] public enum TJTransformOptions { PERFECT = 1, TRIM = 2, CROP = 4, GRAY = 8, NOOUTPUT = 16, } public static readonly Dictionary<TJPixelFormats, int> PixelSizes = new Dictionary<TJPixelFormats, int> { { TJPixelFormats.TJPF_RGB, 3}, { TJPixelFormats.TJPF_BGR, 3}, { TJPixelFormats.TJPF_RGBX, 4}, { TJPixelFormats.TJPF_BGRX, 4}, { TJPixelFormats.TJPF_XBGR, 4}, { TJPixelFormats.TJPF_XRGB, 4}, { TJPixelFormats.TJPF_GRAY, 1}, { TJPixelFormats.TJPF_RGBA, 4}, { TJPixelFormats.TJPF_BGRA, 4}, { TJPixelFormats.TJPF_ABGR, 4}, { TJPixelFormats.TJPF_ARGB, 4}, { TJPixelFormats.TJPF_CMYK, 4} }; } }