C++圖片格式轉換:BMP轉JPEG
C++方式將BMP格式轉換為JPEG格式,依賴了一個第三方庫,工程下載連結為:點選開啟連結
Bmp2Jpeg.h:
#pragma once
class CBmp2Jpeg
{
public:
CBmp2Jpeg();
~CBmp2Jpeg();
public:
int Bmp2Jpeg(const char *bmp, const char *jpeg);
private:
int SaveJpeg(const char *filename, unsigned char *bits, int width, int height, int depth);
int ReadBmp(const char *bmp, unsigned char **data,int &w, int &h, int &d);
void Bgra2Rgb(const unsigned char *src, int w, int h, int d, unsigned char *dst);
void InitFileHeader(void *pFile, void *fileHeader);
void InitInfoHeader(void *pFile, void *infoHeader);
void SaveBmp(void *fileHeader, void *infoHeader, int bitCount, unsigned char *data, const char *savename);
private:
int m_quality; //它的大小決定jpg的質量好壞
enum{
JPEG_QUALITY = 100,
};
};
Bmp2Jpeg.cpp:
#include <iostream>
#include<Windows.h>
#include <fstream>
//#include<stdlib.h>
#include "Bmp2Jpeg.h"
#include <vector>
extern "C"
{
#include "jpeglib.h"
};
#pragma comment(lib,"libjpeg.lib")
using namespace std;
#pragma pack(2)
struct bmp_fileheader //檔案頭,長度為14Byte固定
{
unsigned short bfType;
unsigned long bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned long bfOffBits;
};
struct bmp_infoheader //檔案資訊頭,長度為40Byte固定
{
unsigned long biSize;
unsigned long biWidth;
unsigned long biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
unsigned long biXPelsPerMeter;
unsigned long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
};
struct RGBPallete
{
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char alpha;
};
CBmp2Jpeg::CBmp2Jpeg() :
m_quality(JPEG_QUALITY)
{
}
CBmp2Jpeg::~CBmp2Jpeg()
{
}
/*===================================================================================
function: jpeg壓縮
input: 1:生成的檔名,2:bmp的指標,3:點陣圖寬度,4:點陣圖高度,5:顏色深度
return: int
description: bmp的畫素格式為(RGB)
===================================================================================*/
int CBmp2Jpeg::SaveJpeg(const char *filename, unsigned char *bits, int width, int height, int depth)
{
FILE * outfile; /* target file */
fopen_s(&outfile, filename, "wb");
if (outfile == NULL) {
return -1;
}
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = width; /* image width and height, in pixels */
cinfo.image_height = height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, m_quality, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&cinfo, TRUE);
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
row_stride = width * depth; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height) {
//這裡我做過修改,由於jpg檔案的影象是倒的,所以改了一下讀的順序
//row_pointer[0] = & bits[cinfo.next_scanline * row_stride];
row_pointer[0] = & bits[(cinfo.image_height - cinfo.next_scanline - 1) * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
return 0;
}
void CBmp2Jpeg::InitFileHeader(void *pFile, void *fileHeader)
{
bmp_fileheader *pfileHeader = (bmp_fileheader *)fileHeader;
fstream *filein = (fstream *)pFile;
//初始化檔案頭
pfileHeader->bfType = 0;
pfileHeader->bfSize=0;
pfileHeader->bfReserved1=0;
pfileHeader->bfReserved2=0;
pfileHeader->bfOffBits=0;
//讀點陣圖檔案頭並輸出相應資訊
filein->read((char*)fileHeader, sizeof(bmp_fileheader));
}
void CBmp2Jpeg::InitInfoHeader(void *pFile, void *infoHeader)
{
bmp_infoheader *pinfoHeader = (bmp_infoheader *)infoHeader;
fstream *filein = (fstream *)pFile;
//初始化資訊頭
pinfoHeader->biSize=0;
pinfoHeader->biWidth=0;
pinfoHeader->biHeight=0;
pinfoHeader->biPlanes=0;
pinfoHeader->biBitCount=0;
pinfoHeader->biCompression=0;
pinfoHeader->biSizeImage=0;
pinfoHeader->biXPelsPerMeter=0;
pinfoHeader->biYPelsPerMeter=0;
pinfoHeader->biClrUsed=0;
pinfoHeader->biClrImportant=0;
//讀點陣圖資訊頭並輸出相應資訊
filein->read((char*)infoHeader, sizeof(bmp_infoheader));
}
void CBmp2Jpeg::SaveBmp(void *fileHeader, void *infoHeader, int bitCount, unsigned char *data, const char *savename)
{
bmp_fileheader *pfileHeader = (bmp_fileheader *)fileHeader;
bmp_infoheader *pinfoHeader = (bmp_infoheader *)infoHeader;
//寫入檔案
std::string str(savename);
str.append(".bmp");
fstream fileout;
fileout.open(str, std::ios::binary | std::ios::out);
fileout.write((char*)fileHeader, sizeof(bmp_fileheader));
fileout.write((char*)infoHeader, sizeof(bmp_infoheader));
fileout.write((char*)data, sizeof(unsigned char) * pfileHeader->bfSize - pfileHeader->bfOffBits);
fileout.close();
}
//讀取並將圖片另存為一個新檔案, 轉換成rgb格式
int CBmp2Jpeg::ReadBmp(const char *bmp, unsigned char **data, int &w, int &h, int &d)
{
//開啟點陣圖檔案
fstream filein;
filein.open(bmp, std::ios::binary | std::ios::in);
if(!filein.is_open())
{
char clog[256] = {0};
sprintf_s(clog, sizeof(clog), "bmp轉jpeg,找不到 %s\n", bmp);
OutputDebugStringA(clog);
return -1;
}
//定義變數
long width=0;
long height=0;
long bitCount=0;
bmp_fileheader fileHeader;
bmp_infoheader infoHeader;
InitFileHeader(&filein, &fileHeader);
if (fileHeader.bfType != 0x4d42)
{
filein.close();
return -1;
}
InitInfoHeader(&filein, &infoHeader);
width=infoHeader.biWidth;
height=infoHeader.biHeight;
bitCount=infoHeader.biBitCount;
int bitPerLine= ((width * bitCount + 31) >> 5) << 2;
int imgSize = abs(height * bitPerLine);
int imgReal = fileHeader.bfSize - fileHeader.bfOffBits;
if(imgSize != imgReal)
{
char clog[256] = {0};
sprintf_s(clog, sizeof(clog), "bmp轉jpeg,影象尺寸不對\n");
OutputDebugStringA(clog);
filein.close();
return -1;
}
if (bitCount == 8)
{
std::vector<RGBPallete> palletes;
unsigned char buf[256 * sizeof(RGBPallete)];
filein.read((char*)buf, 256 * sizeof(RGBPallete));
for (int i = 0; i < 256; i++)
{
RGBPallete pallete;
memcpy(&pallete, buf + i * sizeof(RGBPallete), sizeof(RGBPallete));
palletes.push_back(pallete);
}
unsigned char* pTemp = new unsigned char[imgSize];
filein.read((char*)pTemp, imgSize);
*data = new unsigned char[width * abs(height) * 4];
for (int i = 0; i < imgSize; i++)
{
RGBPallete& p = palletes[pTemp[i]];
memcpy((*data) + i * sizeof(RGBPallete), &p, sizeof(RGBPallete));
}
bitCount = 32;
delete pTemp;
}
else if (bitCount == 24 || bitCount == 32)
{
*data = new unsigned char[imgSize];
filein.read((char*)(*data), imgSize);
filein.close();
}
else
{
filein.close();
return -1;
}
w = width;
h = height;
d = bitCount;
return 0;
}
void CBmp2Jpeg::Bgra2Rgb(const unsigned char *src, int w, int h, int d, unsigned char *dst)
{
unsigned char* pTempDst = dst;
for (int i = 0; i < abs(h); i++)
{
const unsigned char* pTempSrc = nullptr;
if (h > 0)
{
pTempSrc = src + w * i * d;
}
else
{
pTempSrc = src + w * abs( i + h + 1 ) * d;
}
for (int j = 0; j < w; j++)
{
*(pTempDst) = *(pTempSrc + 2);
*(pTempDst + 1) = *(pTempSrc + 1);
*(pTempDst + 2) = *(pTempSrc);
pTempDst += 3;
pTempSrc += d;
}
}
}
int CBmp2Jpeg::Bmp2Jpeg(const char *bmp, const char *jpeg)
{
unsigned char *brga = nullptr; //指向點陣圖buffer的全域性指標,window下畫素格式: BGRA(4個位元組)
int width = 0, height = 0, depth = 0;
if(ReadBmp(bmp, &brga,width, height, depth) < 0)
{
return -1;
}
unsigned char *rgb = new unsigned char[width * abs(height) * depth/8];
Bgra2Rgb(brga, width, height, depth/8, rgb);
int ret = SaveJpeg(jpeg, rgb, width, abs(height), 3);
delete [] brga;
delete [] rgb;
brga = nullptr;
rgb = nullptr;
return ret;
}
呼叫:
#include <iostream>
#include <stdio.h>
#include "Bmp2Jpeg.h"
using namespace std;
int main()
{
CBmp2Jpeg bmp;
bmp.Bmp2Jpeg("111_24.bmp", "lena.jpg");
cout<<"good job."<<endl;
cin.get();
return 0;
}
相關文章
- 將bmp檔案轉換成JPEG(待修改,目前可轉換但圖片倒轉)
- 怎麼將bmp格式圖片轉換jpg格式的
- 常見圖片格式:PNG,JPG/JPEG,BMP
- 圖片格式轉換,JPG圖片轉換成PDF
- heic圖片轉換格式怎麼轉?
- 圖片格式怎麼轉換,如何轉換jpg
- 怎麼把Excel 表格轉成PNG、JPEG、GIF圖片格式 ?Excel
- jpeg,png,bmp轉換成icon,windows本地匯出icon檔案Windows
- ppm轉換bmp
- 怎麼轉換圖片格式並壓縮圖片
- 圖片格式轉換器有什麼,怎麼無損轉換heic格式
- 教程:怎麼轉換heic格式圖片
- WidsMob ImageConvert for Mac 圖片格式轉換器Mac
- 如何將heic格式轉換成jpg圖片?
- bmp是什麼格式的檔案 怎麼把jpg轉換為bmp
- 前端圖片canvas,file,blob,DataURL等格式轉換前端Canvas
- 批次HEIC格式圖片轉換工具 iMazing HEIC Converter
- 視訊音樂圖片格式轉換Permute 3
- js圖片 轉換JS
- 開源圖片工具箱(Img Toolbox) 格式轉換 新增水印 圖片壓縮 圖片裁剪 圖片旋轉 圖片縮放
- Pytorch視覺化(顯示圖片)及格式轉換PyTorch視覺化
- 怎麼將heic轉為jpg格式,哪個圖片轉換器好用
- 圖片怎麼轉換成PDF,圖片轉PDF教程
- 圖片轉換文字appAPP
- 線上SVG轉換,支援SVG to PNG、SVG to JPEG、SVG to WEBP 圖片轉換操作-toolfk程式設計師線上工具網SVGWeb程式設計師
- 如何將圖片轉word?圖文轉換選轉易俠
- PythonGUI工具 圖片大小轉換PythonNGUI
- element上傳圖片元件使用方法|圖片回顯|格式轉換base64元件
- 圖片轉換成文字怎麼轉?一鍵轉換看這裡
- Java實現emf轉jpg png 圖片轉換Java
- 圖片轉換成文字線上能轉嗎?
- JPG轉CAD,JPG圖片如何轉換成CAD圖紙?
- 利用網路請求將網路圖片轉換成Bitmap格式
- 如何把圖片轉換成文字?轉換工具用哪個?
- 影像格式轉換
- 如何將圖片轉換成影片?
- 圖片heic怎麼轉換jpg?
- python批量ppt轉圖片,pdf轉圖片,word轉圖片指令碼Python指令碼