1. 程式人生 > >C# 使用libjpeg-turbo解壓圖片的程式碼

C# 使用libjpeg-turbo解壓圖片的程式碼

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}
        };

    }
}