Jpeg压缩实现

本文提供了C++实现的JPEG压缩代码,包括CDib类的详细实现,涉及BMP图像数据解析、DCT变换、量化、行程编码、Huffman编码等关键步骤。通过对图像数据进行处理,实现了从24位BMP图像到Jpeg编码的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前说过需要Jpeg代码的可以发邮件联系我,因为最近比较忙,恕不能一一回复。只好在这里将主要的实现代码写下拉,大家需要的话可以自己研究。

一。CDib类实现BMP图像数据解析与Jpeg编码

Dib.h

// Dib.h: interface for the CDib class.
//
//

#if !defined(AFX_DIB_H__FE6314AF_2346_49AE_A383_AA4421DBBF12__INCLUDED_)
#define AFX_DIB_H__FE6314AF_2346_49AE_A383_AA4421DBBF12__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


//戴玉超 2005,12,28
class CDib : public CObject 
{
public:
 CDib();
 virtual ~CDib();
 DWORD GetHeight()  //得到图像的高度
 {
  return dwHeight;
 }
 DWORD GetWidth()  //得到图像的宽度
 {
  return dwWidth;
 }
 BOOL Is24bit()    //判断是否24位bmp图像
 {
  return m_bit24;
 }
private:

 DWORD dwHeight;  // Height of the map

 DWORD dwWidth;   // Width of the map

 BOOL m_bit24;    // is a 24bit map

public:
 BOOL RGB2YCbCr(double *rgb,double *yrr); // 实现RGB颜色空间到YCrCb颜色空间的变换

 BOOL SetPalette(CDC *pDC);               // 设置调色板

 BOOL Draw(CDC* pDC, CPoint origin);      // 图形绘制 

 BOOL SaveImage(LPCTSTR lpszFileName);    // 保存图像

 void LoadImage(LPCTSTR lpszFileName);    // 加载图像

public:
 BOOL Write32BitData(int nData);          // 写入32位数据

 BOOL Quant(double *data,int * table,unsigned char * QuantTable); // 根据给定的量化表实现8*8块的量化

 BOOL DCT_1D(double *data,double *temp);           // 一维DCT

 BOOL DCT(double * sourcedata);                    // 二维DCT

 BOOL YCbCr2RGB(double * yrr, double *rgb);        // 实现YCrCb颜色空间到RGB颜色空间的变换

 BOOL RunLengthCode(int * table, int * RLC_length);  // 行程编码

 void CDib::ShiftWrite(int huffmanbitnum,int huffmancode);  // 按位写入数据

 BOOL CDib::WriteSurplus();                         // 写最后的位

 BOOL SaveAsJpeg(LPCTSTR lpszFileName);             //保存为Jpeg图像

 BOOL Jpeg();                                        //完成 Jpeg压缩的全过程

 int CDib::WriteData(int nPreDCdata,int * table,int *DChufco,int *DChufsi,int *AChufco,int *AChufsi); //写入数据

 BOOL CDib::HuffmanTable(unsigned char *bit,unsigned char*val);  //Huffman编码

public:
 int HuffmanCode[251],HuffmanLength[251];   //Huffman码字和位

 PBYTE pDibData;                             //数据

 CFile file;                                 //文件指针

 struct RLC
 {

  int digit;
  int length;
 } rlc[64];     //记录8*8的游程数据

 unsigned char * m_pDibBits;  // pointer to the rgb data;

 int m_nPaletteEntries;       // 调色板数量

 RGBQUAD * m_pPalette;        // 调色板

 CPalette m_Palette;          //

 DWORD m_dwDibSize;           //文件大小

 BITMAPINFOHEADER * m_pBIH;    // bmp文件头信息

 unsigned char * m_pDib;       //指向数据的指针

 int EncodeJpeg;     //32位的数据缓冲区,用于把不等长的码串串成4个字节以便写入JPEG文件

 int surplus;     //32位数据缓冲区中剩余没使用的位长,使用数据缓冲区从高位到低位
};

#endif // !defined(AFX_DIB_H__FE6314AF_2346_49AE_A383_AA4421DBBF12__INCLUDED_)

 

Dib.cpp

// Dib.cpp: implementation of the CDib class.
//
//

#include "stdafx.h"
#include "JpegCompression.h"
#include "Dib.h"
#include "math.h"
#include "iostream.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

const double  pi = 3.1415926535;
extern unsigned char LumQuantTable[64];        //亮度量化表
extern unsigned char ChrQuantTable[64];        //色差量化表
extern  short ZigzagTable[8*8];                //ZigZag扫描

extern unsigned int LumDCValue[12];            //亮度DC码值
extern unsigned int ChrDCValue[12];            //色差DC码值
extern unsigned char LumACHuffmanVal[162];    
extern unsigned char ChrACHuffmanVal[162];

extern unsigned char LumDCHuffmanBit[17];  //亮度DC哈夫曼表的位值 
extern unsigned char LumDCHuffmanVal[12];     //亮度DC哈夫曼表的码值
extern unsigned char LumACHuffmanBit[17];     //亮度AC哈夫曼表的位值

extern unsigned char ChrDCHuffmanBit[17];
extern unsigned char ChrDCHuffmanVal[12];
extern unsigned char ChrACHuffmanBit[17];


extern int LumDCHuffmanLen[12];
extern int LumDCHuffmanCode[12];

extern int LumACHuffmanLen[162];
extern int LumACHuffmanCode[162];

extern int ChrDCHuffmanLen[12];
extern int ChrDCHuffmanCode[12];

extern int ChrACHuffmanLen[162];
extern int ChrACHuffmanCode[162];
//
// Construction/Destruction
//

CDib::CDib()  //构造函数
{
 m_pDib = NULL;
 pDibData = NULL;
 m_bit24 = 0;
 surplus = 32;
 EncodeJpeg=0;
}


CDib::~CDib()
{
}

//加载图像
void CDib::LoadImage(LPCTSTR lpszFileName)
{
 CFile cf;
 LPBYTE pDib = NULL;
 DWORD dwDibSize = 0;
 try
 {
  if(!cf.Open(lpszFileName,CFile::modeReadWrite,NULL))
  {
   throw new CException;
  }
  dwDibSize = cf.GetLength() - sizeof(BITMAPFILEHEADER);
  pDib = (LPBYTE)VirtualAlloc(NULL,dwDibSize,MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
  if (pDib == NULL)
  {
   AfxMessageBox("Error in allocate space!");
  }
  BITMAPFILEHEADER * pBMPHeader = new BITMAPFILEHEADER;
  if(cf.Read(pBMPHeader,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
  {
   throw new CException;
  }
  if(pBMPHeader->bfType != 0x4d42)
  {
   throw new CException;
  }
  if(cf.ReadHuge(pDib,dwDibSize) != dwDibSize)
  {
   throw new CException;
  }
  if(m_pDib != NULL)
  {
   delete m_pDib;
  }
  m_pDib = pDib;
  
  m_dwDibSize = dwDibSize;
  
  m_pBIH = (BITMAPINFOHEADER *)pDib;
  
  m_pPalette = (RGBQUAD *)&m_pDib[sizeof(BITMAPINFOHEADER)];
  
  m_nPaletteEntries = 1<< m_pBIH->biBitCount;
  
  if (m_pBIH->biBitCount > 8)
  {
   m_nPaletteEntries = 0;
  }
  
  else if (m_pBIH->biClrUsed != 0)
  {
   m_nPaletteEntries = m_pBIH->biClrUsed;
  }
  
  m_pDibBits = m_pDib + sizeof(BITMAPINFOHEADER) + m_nPaletteEntries * sizeof(RGBQUAD);
  
  if(m_Palette.GetSafeHandle() != NULL)
  {
   m_Palette.DeleteObject();
  }
  
  if (m_nPaletteEntries != 0)
  {
   LOGPALETTE *pLogPal =
    (LOGPALETTE *)new char[sizeof(LOGPALETTE) + m_nPaletteEntries * sizeof(PALETTEENTRY)];
   if (pLogPal != NULL)
   {
    pLogPal->palVersion = 0x300;
    pLogPal->palNumEntries = m_nPaletteEntries;
    for(int i = 0; i < m_nPaletteEntries; i++)
    {
     pLogPal->palPalEntry[i].peRed = m_pPalette[i].rgbRed;
     pLogPal->palPalEntry[i].peGreen = m_pPalette[i].rgbGreen;
     pLogPal->palPalEntry[i].peBlue = m_pPalette[i].rgb

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值