1. 程式人生 > >基於libjpeg庫實現JPEG圖片壓縮程式碼實現(程式碼普適性強)

基於libjpeg庫實現JPEG圖片壓縮程式碼實現(程式碼普適性強)

本文先把程式碼貼上,後續會講解原理及實現過程

1、從官網上下載jpeg原始碼,編譯成庫(本人在windows下編譯),編譯方法網上很多,這裡不敘述。

2、新增庫檔案和jpeglib.h、jmorecfg.h、jconfig.h至工程中

3、程式碼實現(VS2013)

#define JPEG_QUALITY 97     //它的大小決定jpg的質量好壞

//#include <atlbase.h> 
#include <afxwin.h>
#include <iostream>
#include<ctime>
using namespace std;
extern "C" {
#include "jpeglib.h"
#include "jmorecfg.h"
#include "jconfig.h"
#include "jerror.h"
}
typedef struct                       /**** BMP file header structure ****/
{
unsigned int   bfSize;           /* Size of file */
unsigned short bfReserved1;      /* Reserved */
unsigned short bfReserved2;      /* ... */
unsigned int   bfOffBits;        /* Offset to bitmap data */
} BITMAPFILEHEADER1;


typedef struct                       /**** BMP file info structure ****/
{
unsigned int   biSize;           /* Size of info header */
int            biWidth;          /* Width of image */
int            biHeight;         /* Height of image */
unsigned short biPlanes;         /* Number of color planes */
unsigned short biBitCount;       /* Number of bits per pixel */
unsigned int   biCompression;    /* Type of compression to use */
unsigned int   biSizeImage;      /* Size of image data */
int            biXPelsPerMeter;  /* X pixels per meter */
int            biYPelsPerMeter;  /* Y pixels per meter */
unsigned int   biClrUsed;        /* Number of colors used */
unsigned int   biClrImportant;   /* Number of important colors */
} BITMAPINFOHEADER1;


typedef struct tagRGBQUAD1{
BYTE rgbBlue;//藍色的亮度(值範圍為0-255)  
BYTE rgbGreen;//綠色的亮度(值範圍為0-255)  
BYTE rgbRed;//紅色的亮度(值範圍為0-255)  
BYTE rgbReserved;//保留,必須為0  

}RGBQUAD1;

/*bmp格式圖片,輸出jpeg的名字,質量因子*/

void bmptojpg(const char *strSourceFileName, const char *strDestFileName, int quality)
{
BITMAPFILEHEADER bfh;// bmp檔案頭
BITMAPINFOHEADER bih;// bmp頭資訊
RGBQUAD rq[256];// 調色盤
int nAdjust;// 用於位元組對齊


BYTE *data = NULL;//new BYTE[bih.biWidth*bih.biHeight];
//BYTE *pDataConv = NULL;//new BYTE[bih.biWidth*bih.biHeight];
int nComponent = 0;


// 開啟影象檔案
FILE *fp = fopen(strSourceFileName, "rb");
if (fp == NULL)
{
printf("Open file error!\n");
return;
}
// 讀取檔案頭
fread(&bfh, sizeof(bfh), 1, fp);
// 讀取影象資訊
fread(&bih, sizeof(bih), 1, fp);


switch (bih.biBitCount)
{
case 8://灰度圖
if (bfh.bfOffBits - 1024<54)
{
fclose(fp);
return;
}
// 8位位元組對齊
nAdjust = bih.biWidth % 4;
if (nAdjust) nAdjust = 4 - nAdjust;


data = new BYTE[(bih.biWidth + nAdjust)*bih.biHeight];
//pDataConv = new BYTE[bih.biWidth*bih.biHeight];


// 定位調色盤,並讀取調色盤
fseek(fp, bfh.bfOffBits - 1024, SEEK_SET);
fread(rq, sizeof(RGBQUAD), 256, fp);
// 讀取點陣圖
fread(data, (bih.biWidth + nAdjust)*bih.biHeight, 1, fp);
fclose(fp);
nComponent = 1;
break;
case 24://RGB
{
// 8位位元組對齊
nAdjust = bih.biWidth * 3 % 4;
if (nAdjust) nAdjust = 4 - nAdjust;
data = new BYTE[(bih.biWidth * 3 + nAdjust)*bih.biHeight];
//pDataConv = new BYTE[bih.biWidth*bih.biHeight*3];
fseek(fp, bfh.bfOffBits, SEEK_SET);
fread(data, (bih.biWidth * 3 + nAdjust)*bih.biHeight, 1, fp);
fclose(fp);
for (int j = 0; j<bih.biHeight; j++){
for (int i = 0; i<bih.biWidth; i++)
{
BYTE red = data[j*(bih.biWidth * 3 + nAdjust) + i * 3];
data[j*(bih.biWidth * 3 + nAdjust) + i * 3] = data[j*(bih.biWidth * 3 + nAdjust) + i * 3 + 2];
data[j*(bih.biWidth * 3 + nAdjust) + i * 3 + 2] = red;
}
}
nComponent = 3;
break;
}
default:
fclose(fp);
return;
}


struct jpeg_compress_struct jcs;
struct jpeg_error_mgr jem;


jcs.err = jpeg_std_error(&jem);
jpeg_create_compress(&jcs);


fp = fopen(strDestFileName, "wb");
if (fp == NULL)
{
fprintf(stderr, "can't open %s\n", strDestFileName);
delete[] data;
//delete [] pDataConv;
return;
}
jpeg_stdio_dest(&jcs, fp);


jcs.image_width = bih.biWidth; // 為圖的寬和高,單位為畫素 
jcs.image_height = bih.biHeight;
jcs.input_components = nComponent;// 1,表示灰度圖, 如果是彩色點陣圖,則為3 
if (nComponent == 1)
jcs.in_color_space = JCS_GRAYSCALE; //JCS_GRAYSCALE表示灰度圖,JCS_RGB表示彩色影象 
else
jcs.in_color_space = JCS_RGB;


jpeg_set_defaults(&jcs);//compression parameter selection 更新引數


// 影象取樣率,預設為2 * 2
jcs.comp_info[0].v_samp_factor = 1;
jcs.comp_info[0].h_samp_factor = 1;


jpeg_set_quality(&jcs, quality, true);


//start = clock();
jcs.dct_method = JDCT_ISLOW;
//jcs.dct_method = JDCT_IFAST;
//jcs.dct_method = JDCT_FLOAT;
//finish = clock();
//cout << finish - start << "/" << CLOCKS_PER_SEC << " (s) " << endl;
//jcs.dct_method = JDCT_FASTEST;


jpeg_start_compress(&jcs, TRUE);//一旦呼叫了該介面,便不能修改任何引數


JSAMPROW row_pointer[1];// 一行點陣圖
int row_stride;// 每一行的位元組數 


row_stride = jcs.image_width*nComponent;// 如果不是索引圖,此處需要乘以3


// 對每一掃描行進行壓縮
while (jcs.next_scanline < jcs.image_height) {
row_pointer[0] = &data[(jcs.image_height - jcs.next_scanline - 1) * (row_stride + nAdjust)];//與官方文件裡的區別:這裡生成的圖片是正的,官方是倒的
jpeg_write_scanlines(&jcs, row_pointer, 1);//1表示一行
}


jpeg_finish_compress(&jcs);


jpeg_destroy_compress(&jcs);//jpeg_abort_compress(&jcs),jpeg_abort(&jcs)


fclose(fp);
delete[] data;


}

int main(int argc, char* argv[])
{
bmptojpg("f6.bmp", "3_11.jpg", 100);
//getchar();
return 0;
}



相關推薦

基於libjpeg實現JPEG圖片壓縮程式碼實現程式碼

本文先把程式碼貼上,後續會講解原理及實現過程1、從官網上下載jpeg原始碼,編譯成庫(本人在windows下編譯),編譯方法網上很多,這裡不敘述。2、新增庫檔案和jpeglib.h、jmorecfg.h、jconfig.h至工程中3、程式碼實現(VS2013)#define

基於libjpeg實現JPEG圖片解碼程式碼實現程式碼

準備工作同上篇一致。JPEG壓縮基於libjpeg中的example.c進行擴充套件編寫解碼原理及實現後續會進行介紹程式碼部分:#include <afxwin.h>#include <setjmp.h>extern "C" {#include "jp

IJLJPEG圖片壓縮

長度 def 釋放 dll rom tmp 一級目錄 加載 ever   如何將比較大的圖片壓縮成比較小的圖片,通常在相機一直拍圖且需要將圖片網絡傳輸時,必須壓縮圖片。相機一般幾十FPS,每張幾M,只能用JPEG有順壓縮才能到可以實時傳輸要求。 還有就是這種特定情況壓縮需要

Android 實現圖片 Exif 的修改Android 自帶的方法

很多時候我們都要對我們的圖片資訊進行一些處理,比如向圖片中寫入經緯度,拍攝時間,裝置資訊,作者等等。這個時候我們就要對我們的圖片Exif進行寫入資訊的操作,當然,我們想知道圖片的Exif資訊,也可以對E

php實現base64圖片上傳方式例項程式碼 前端介面問題

php實現base64圖片上傳方式例項程式碼 html程式碼 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transit

Linux--使用libjpeg解碼jpg圖片

使用libjpeg庫解碼jpg圖片 libjpeg版本:v6b 執行環境:arm /* *函式功能:解碼jpg圖片,儲存解碼出來的資料 *函式引數:pPic記錄源jpg圖片,解碼得到圖片寬高、位深度、顯示資料 *返回值 :解碼正確返回0,錯誤返回-1

php實現base64圖片上傳方式例項程式碼 前端介面問題

php實現base64圖片上傳方式例項程式碼 html程式碼 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/x

Vue directive自定義指令+canvas實現H5圖片壓縮上傳-Base64格式

前言 最近優化專案-手機拍照圖片太大,回顯速度比較慢,使用了vue的自定義指令實現H5壓縮上傳base64格式的圖片 canvas自定義指令 Vue.directive("canvas",

基於springBoot實現圖片新增文字水印附原始碼

原始碼在最下面 程式背景 在網路中的很多地方都有水印的存在,比如微信公眾號上面的圖片,微博 等……所以老闆也要求我們在圖片上傳時新增自己的水印。 所以寫了一個工具類。

基於Lire搜尋相似圖片

什麼是Lire LIRE(Lucene Image REtrieval)提供一種的簡單方式來建立基於影象特性的Lucene索引。利用該索引就能夠構建一個基於內容的影象檢索(content- based image retrieval,CBIR)系統,來搜尋相似的影象。LIR

Django 實現前端圖片壓縮

思路: <img alt="" src="/img/圖片真實地址" ></img> 上面是一個典型的HTML中的圖片,在django中,src對應的path會經過url進

批量更新程式碼整理程式碼從陣列中批量取資料的方法

查詢出所有的資料,分批插入。從原來的所有的list 資料裡面,每次拿出X 條資料,再批量更新 public void insertStudent() { List<Student> list = studentDao.listAllStudentForStat(); i

基於GDAL,讀取海洋風場資料.nc格式c++版

        經過這一段時間的對海洋資料的處理,接觸了大量的與海洋相關的資料,例如海洋地形、海洋表面溫度、鹽度、溼度、雲場、風場等資料,除了地形資料是grd格式外,其他的都是nc格式的資料。本文將以海洋風場資料為例,進行nc格式檔案的讀取。    

微信小程式如何實現下拉框效果?程式碼示例

wxml程式碼: <view class='top-text'> 選擇接收班級</view> <!-- 下拉框 --> <view class='top-selected' bindtap='bindShowMsg'> <

JS—圖片壓縮上傳單張

eight ascii value size set tsa ade ready chan *vue+webpack環境,這裏的that指到vue實例 &lt;input type="file" name="file" ac

粒子濾波初探利用粒子濾波實現視訊目標跟蹤-程式碼部分C++&&opencv2.49

利用粒子濾波實現視訊目標跟蹤工程實戰 放在最前:致謝taotao1233、yangyangcv、yang_xian521 以及先驅 Rob Hess 所開源的程式碼和思路。 本篇:基本為工程翻譯,以及對上面版本的一些修正,使用的是opencv2.49,以Ma

Android自制圖片的三級快取程式碼+講解

Android的圖片三級快取機制 首先 圖片的三計劃快取的概念 泛指的是 -記憶體快取 -本地快取 -網路快取 記憶體快取的概念: 應用程式在執行時 WindowMeanger會分配給 應用 相應的執行時記憶體 執行是記憶體的大小根據and

ubuntu 12.04 簡單配置samba服務,實現主機與虛擬機互通設置Windows虛擬盤

完成 sam inux ... conf restart bridged 要求 system 環境: virtualbox ubuntu12.04 首先,如果你到這步了,說明你的window與linux的網絡已經配好了,他們之間是可以互相Ping通的,如果沒有,請看我以

EF6 在原有數據中使用 CodeFirst 總復習五、生成發帖頁面

數據 ctrl 記得 自動 rst 默認值 string 頁面 ont 有點與在原有數據庫中使用 CodeFirst 遠了,不過是總復習嗎,總得全面點。 一、在用戶表(Users)中插入兩個用戶 二、生成發帖界面 MVC生成的界面很多,也沒使用Ajax,實際開

EF6 在原有數據中使用 CodeFirst 總復習一、搭建基礎環境

width eight tle sca 使用 圖片 zh-cn span del 本來以為已經會了,可動手時發現許多問題還是模糊不清,正所謂眼高手低。只能重新查資料,再復習一遍。 vs.net2013 ef6 mvc5 sqlserver2008 一、建立數據