1、下载:
libjpeg-turbo 下载地址 :https://github.com/libjpeg-turbo/libjpeg-turbo
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}
};
}
}