⑴ 如何使用libjpeg
本文只介紹jpeg壓縮的相關內容,剛開始我貪圖省事,採用微 軟 的GDI Plus提供的功能,很是方便,先獲取jpg圖像的編碼,然後根據圖像的點陣圖數據創建一個Bitmap類的對象,再保存圖像為jpg格式就行了。但是我對 GDI+還是很信任,總感覺不踏實(沒有理由的),我們的系統一旦安裝就要長期運行,我就是擔心長期運行一段時間後GDI+會出問題,結果也證實了我的擔 心,我們實際使用的10套系統中有一套,連續運行3-5天後,GDI+就會崩潰,於是我決心採用IJG JPEG Library。您可以到
站下載libjpeg的源碼, IJG JPEG Library就是jpeg壓縮庫,是以源碼的形式提供給軟體開發人員的,當然在軟體包里也有編譯好的庫文件,我們這里就只用到其中的 libjpeg.lib,jconfig.h,jmorecfg.h,jpeglib.h這幾個文件,下面我就介紹一下怎樣在自己的程序里嵌入圖像壓縮功 能。
一、建立編譯環境
所謂建立編譯環境,其實非常簡單,就是把上面提到的4個文件拷 貝到你的項目文件夾下,把libjpeg.lib添加到你的項目中,然後在你完成壓縮功能的那個文件里加入#include "jpeglib.h",需要注意的是,libjpeg.lib是用c語言開發的,如果要用在你的C++程序里,需要用到extern "C",如下:
// TestLibjpeg.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "memory.h"
extern "C" {
#include "jpeglib.h"
}
二、壓縮步驟
1、申請並初始化jpeg壓縮對象,同時要指定錯誤處理器
struct jpeg_compress_struct jcs;
// 聲明錯誤處理器,並賦值給jcs.err域
struct jpeg_error_mgr jem;
jcs.err = jpeg_std_error(&jem);
jpeg_create_compress(&jcs);
2、指定壓縮後的圖像所存放的目標文件,注意,目標文件應以二進制模式打開
f=fopen("03.jpg","wb");
if (f==NULL)
{
delete [] data;
delete [] pDataConv;
return 0;
}
jpeg_stdio_dest(&jcs, f);
3、設置壓縮參數,主要參數有圖像寬、高、色彩通道數(1:索引圖像,3:其他),色彩空間(JCS_GRAYSCALE表示灰度圖,JCS_RGB表示彩色圖像),壓縮質量等,如下:
jcs.image_width = nWidth; // 為圖的寬和高,單位為像素
jcs.image_height = nHeight;
jcs.input_components = 1; // 在此為1,表示灰度圖, 如果是彩色點陣圖,則為3
jcs.in_color_space = JCS_GRAYSCALE; //JCS_GRAYSCALE表示灰度圖,JCS_RGB表示彩色圖像
jpeg_set_defaults(&jcs);
jpeg_set_quality (&jcs, 80, true);
需要注意的是,jpeg_set_defaults函數一定要等設 置好圖像寬、高、色彩通道數計色彩空間四個參數後才能調用,因為這個函數要用到這四個值,調用jpeg_set_defaults函數後,jpeglib 庫採用默認的設置對圖像進行壓縮,如果需要改變設置,如壓縮質量,調用這個函數後,可以調用其它設置函數,如jpeg_set_quality函數。其實 圖像壓縮時有好多參數可以設置,但大部分我們都用不著設置,只需調用jpeg_set_defaults函數值為默認值即可。
4、上面的工作準備完成後,就可以壓縮了,壓縮過程非常簡單, 首先調用jpeg_start_compress,然後可以對每一行進行壓縮,也可以對若干行進行壓縮,甚至可以對整個的圖像進行一次壓縮,壓縮完成後, 記得要調用jpeg_finish_compress函數,如下:
jpeg_start_compress(&jcs, TRUE);
JSAMPROW row_pointer[1]; // 一行點陣圖
int row_stride; // 每一行的位元組數
row_stride = jcs.image_width; // 如果不是索引圖,此處需要乘以3
// 對每一行進行壓縮
while (jcs.next_scanline < jcs.image_height) {
row_pointer[0] = & pDataConv[jcs.next_scanline * row_stride];
jpeg_write_scanlines(&jcs, row_pointer, 1);
}
jpeg_finish_compress(&jcs);
5、最後就是釋放壓縮工作過程中所申請的資源了,主要就是jpeg壓縮對象,由於在本例中我是直接用的局部變數,所以只需調用jpeg_destroy_compress這個函數即可,如下:
jpeg_destroy_compress(&jcs);
三、解壓縮步驟
解壓縮步驟與壓縮步驟非常相似,只是解壓縮對象為jpeg_decompress_struct類型,步驟如下:
1、聲明並初始化解壓縮對象,同時制定錯誤信息管理器
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
2、打開jpg圖像文件,並指定為解壓縮對象的源文件
FILE *f = fopen(strSourceFileName,"rb");
if (f==NULL)
{
printf("Open file error!\n");
return;
}
//
jpeg_stdio_src(&cinfo, f);
3、讀取圖像信息
jpeg_read_header(&cinfo, TRUE);
4、根據圖像信息申請一個圖像緩沖區
data = new BYTE cinfo.image_width*cinfo.image_height*cinfo.num_components];
5、開始解壓縮
jpeg_start_decompress(&cinfo);
JSAMPROW row_pointer[1];
while (cinfo.output_scanline < cinfo.output_height)
{
row_pointer[0] = &data[(cinfo.output_height - cinfo.output_scanline-1)*cinfo.image_width*cinfo.num_components];
jpeg_read_scanlines(&cinfo,row_pointer ,
1);
}
jpeg_finish_decompress(&cinfo);
6、釋放資源
jpeg_destroy_decompress(&cinfo);
fclose(f);
好了,利用IJG JPEG Library進行圖像壓縮就介紹到這里,希望對大家有所幫助,實例代碼已經實現了圖像的壓縮和解壓縮的全部功能,命令格式 為:「TestLibjpeg.exe j|j24|b 源文件名 目標文件名」,其中,j選項將源文件壓縮為jpg格式,不改變色彩模式,j24選項將源文件壓縮為24為jpg格式,b選項將源文件解壓縮為bmp格式, 該實例並沒有提供文件有效性的驗證,如果要引入自己的代碼,請自己實現文件有效性的驗證。
⑵ 什麼是GDI
兩個意思,一個是圖形設備介面的英文縮寫;另一個是全球防衛組織。
GDI(全球防衛組織):
全球防禦組織是世界上最發達國家的軍事化國際聯盟,由Westwood Studios(後來的EA)為美國的個人電腦發行了一系列即時戰略游戲「命令與征服」,與凱恩領導的NOD兄弟會和入侵地球的思金人斗爭。
GDI(圖形設備介面):
GDI的主要任務是在系統和繪圖程序之間交換信息,並處理所有Windows程序的圖形輸出。在Windows操作系統下,大多數具有圖形界面的應用程序都離不開GDI。藉助GDI提供的功能,圖形和文本可以輕松地輸出到屏幕、列印機和其他輸出設備上。
(2)gdi壓縮jpg擴展閱讀:
GDI(圖形設備介面)的特點:
1、不允許程序直接訪問物理顯示硬體,通過稱為「設備環境」的抽象介面間接訪問顯示硬體;
2、程序需要與顯示硬體(顯示器、列印機等) 進行通訊時,必須首先獲得與特定窗口相關聯的設備環境;
3、用戶無需關心具體的物理設備類型;
4、Windows參考設備環境的數據結構完成數據的輸出。