c++处理图片

来源:互联网 发布:黄牛党抢票软件 编辑:程序博客网 时间:2024/04/28 06:47

包括读取,保存,格式转换,图片优化等等。其中使用了MS的ijl151库把jpg转换成bmp。

// TestConsole.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <atlimage.h>
#include <fstream>

#include "ijl151.h"
#pragma comment(lib, "ijl151")

using namespace std;

#include <pshpack2.h>  //指定补位值为2
struct sunBITMAPFILEHEADER
{
 WORD bfType;   //位图文件类型,必须为BMP
 DWORD bfSize;   //位图文件大小,以字节为单位
 WORD bfReserved;  //位图文件保留字,必须为0
 WORD bfReservedEx;  //位图文件保留字,必须为0
 DWORD bfOffBits;  //位图数据的起始位置,相对于位图文件头的偏移量,以字节为单位
};
#include <poppack.h>

int bmpWidth  = 0;
int bmpHeight = 0;
int biBitCount= 0;
int lineByte  = 0;
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
RGBQUAD* pColorTable= NULL;
unsigned char* pBmpBuf = NULL;

bool readBmp(char *bmpName)
{
 FILE *fp=fopen(bmpName,"rb");//二进制读方式打开指定的图像文件
 if(fp==0)
 {
  return 0;
 }
 fread(&fileHeader,sizeof(char),sizeof(BITMAPFILEHEADER),fp);
 //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
 fread(&infoHeader,1,sizeof(BITMAPINFOHEADER),fp);
 //获取图像宽、高、每像素所占位数等信息
 bmpWidth = infoHeader.biWidth;
 bmpHeight = infoHeader.biHeight;
 biBitCount = infoHeader.biBitCount;
 //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
 lineByte=(bmpWidth * biBitCount/8+3)/4*4;
 //灰度图像有颜色表,且颜色表表项为256
 if(biBitCount==8)
 {
  //申请颜色表所需要的空间,读颜色表进内存
  pColorTable = new RGBQUAD[256];
  fread(pColorTable,sizeof(RGBQUAD),256,fp);
 }
 //申请位图数据所需要的空间,读位图数据进内存
 pBmpBuf = new unsigned char[lineByte * bmpHeight];
 fread(pBmpBuf,1,lineByte * bmpHeight,fp);
 //关闭文件
 fclose(fp);
 return TRUE;
}

void saveBmp()
{
 FILE *fp=fopen("e:\testBmp\222.bmp","wb");
 if (NULL == fp)
 {
  cout << "open file error in saveBmp()" << endl;
  return;
 }
 //写文件头进文件

 fwrite(&fileHeader,1,sizeof(BITMAPFILEHEADER),fp);
 fwrite(&infoHeader,1,sizeof(BITMAPINFOHEADER),fp);
 if (NULL != pColorTable)
 {
  fwrite(&fileHeader,1,sizeof(RGBQUAD)*256,fp);
 }
 fwrite(pBmpBuf,1,bmpHeight*lineByte,fp);

 if (biBitCount == 8)
 {
  delete []pColorTable;
  pColorTable = NULL;
 }
 delete []pBmpBuf;
 pBmpBuf = NULL;
 fclose(fp);
}
//直方图均衡化处理
BOOL HistogramEqualize()
{
 int i,j;
 int ns_r[256],ns_g[256],ns_b[256];
 memset(ns_r,0,sizeof(ns_r));
 memset(ns_g,0,sizeof(ns_r));
 memset(ns_b,0,sizeof(ns_r));

 int nHeight= abs(top-bottom);
 int nWidth = abs(left-right);

 double ps_r[256],ps_g[256],ps_b[256];
 double temp_r[256],temp_g[256],temp_b[256];
 for (i = 0; i < bmpHeight; i ++) // 对各像素进行灰度转换
 {
  for (j = 0; j < bmpWidth * 3; j ++)
  {
   // 对各像素进行灰度统计
   unsigned char R = *(pBmpBuf + bmpWidth * 3 * i + j);
   ns_r[R]++;
   j++;
   unsigned char G = *(pBmpBuf + bmpWidth * 3 * i + j);
   ns_g[G]++;
   j++;
   unsigned char B = *(pBmpBuf + bmpWidth * 3 * i + j);
   ns_b[B]++;
  }
 }

 for(i=0;i<256;i++) // 计算灰度分布密度
 {
  ps_r[i] = ns_r[i] / (bmpHeight * bmpWidth * 1.0f);
  ps_g[i] = ns_g[i] / (bmpHeight * bmpWidth * 1.0f);
  ps_b[i] = ns_b[i] / (bmpHeight * bmpWidth * 1.0f);
 }

 for(i = 0; i < 256; i++)
 {
  //计算累计直方图分布
  if(i == 0)
  {
   temp_r[0] = ps_r[0];
   temp_g[0] = ps_g[0];
   temp_b[0] = ps_b[0];
  }
  else
  {
   temp_r[i] = temp_r[i-1] + ps_r[i];
   temp_g[i] = temp_g[i-1] + ps_g[i];
   temp_b[i] = temp_b[i-1] + ps_b[i];
  }
  //累计分布取整,nNs_R[]、nNs_G[]、nNs_B[]保存有计算出来的灰度映射关系
  ns_r[i] = (int)(255.0f * temp_r[i] + 0.5f);
  ns_g[i] = (int)(255.0f * temp_g[i] + 0.5f);
  ns_b[i] = (int)(255.0f * temp_b[i] + 0.5f);
 }

 for (i = 0; i < bmpHeight; i ++)
 {
  for (j = 0; j < bmpWidth * 3; j ++)
  {
   //对R分量进行灰度映射(均衡化)
   unsigned char R = *(pBmpBuf + bmpWidth * 3 * i + j);
   *(pBmpBuf + bmpWidth * 3 * i + j) = ns_r[R];
   j++;
   //对G分量进行灰度映射(均衡化)
   unsigned char G = *(pBmpBuf + bmpWidth * 3 * i + j);
   *(pBmpBuf + bmpWidth * 3 * i + j) = ns_g[G];
   j++;
   //对B分量进行灰度映射(均衡化)
   unsigned char B = *(pBmpBuf + bmpWidth * 3 * i + j);
   *(pBmpBuf + bmpWidth * 3 * i + j) = ns_b[B];
  }
 }
 return TRUE;
}

void saveIjlBmp(BYTE* lpBuffer,DWORD dwSize)
{
 BITMAPFILEHEADER bmfh;
 bmfh.bfType=0x4d42;
 bmfh.bfSize=54+dwSize;
 bmfh.bfReserved1=bmfh.bfReserved2=0;
 bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);//=54;

 BITMAPINFOHEADER bmih;
 bmih.biWidth =bmpWidth;
 bmih.biHeight=bmpHeight;
 bmih.biPlanes=1;
 bmih.biBitCount=24;
 bmih.biCompression=BI_RGB;
 bmih.biSizeImage=bmpWidth*bmpHeight*3;
 bmih.biXPelsPerMeter=0;
 bmih.biYPelsPerMeter=0;
 bmih.biClrUsed=0;
 bmih.biClrImportant=0;
 bmih.biSize=sizeof(BITMAPINFOHEADER);


 FILE* pf=fopen("e:\testBmp\111.bmp","wb");
 fwrite(&bmfh,sizeof(BITMAPFILEHEADER),1,pf);
 fwrite(&bmih,sizeof(BITMAPINFOHEADER),1,pf);
 fwrite(lpBuffer,dwSize,1,pf);
 fclose(pf);
}


BOOL JpgDecode(BYTE *lpSrcBuffer, DWORD dwSrcSize, BYTE *lpDstBuffer, DWORD *dwDstSize, DWORD *lpdwWidth, DWORD *lpdwHeight, DWORD *lpBits, DWORD *dwReserve1)
{
 BOOL bres;
 IJLERR  jerr;
 DWORD dwWholeImageSize;
 int     nPad;

 // Allocate the IJL JPEG_CORE_PROPERTIES structure.
 JPEG_CORE_PROPERTIES jcprops;
 bres = TRUE;

 //__try
 {
  // Initialize the Intel(R) JPEG Library.
  jerr = ijlInit2( &jcprops );
  if(IJL_OK != jerr)
  {
   return FALSE;
  }
  // Get information on the JPEG image
  // (i.e., width, height, and channels).
  jcprops.JPGFile = NULL;
  jcprops.JPGBytes = lpSrcBuffer;
  jcprops.JPGSizeBytes = dwSrcSize;

  jerr = ijlRead2(&jcprops, IJL_JBUFF_READPARAMS);
  if(IJL_OK != jerr)
  {
   return FALSE;
  }
  switch(jcprops.JPGChannels)
  {
  case 1:
   {
    jcprops.JPGColor = IJL_G;
    jcprops.DIBColor = IJL_RGB;
    jcprops.DIBChannels = 3;
    break;
   }
  case 3:
   {
    jcprops.JPGColor = IJL_YCBCR;
    jcprops.DIBColor = IJL_BGR;
    jcprops.DIBChannels = 3;
    break;
   }
  default:
   {
    // This catches everything else, but no
    // color twist will be performed by the IJL.
    jcprops.JPGColor = IJL_OTHER;
    jcprops.DIBColor = IJL_OTHER;
    jcprops.DIBChannels = jcprops.JPGChannels;
    break;
   }
  }

  // Compute size of desired pixel buffer.
  nPad = IJL_DIB_PAD_BYTES(jcprops.JPGWidth,3);
  dwWholeImageSize = (jcprops.JPGWidth*jcprops.DIBChannels+nPad) * jcprops.JPGHeight;


  // Set up the info on the desired DIB properties.
  jcprops.DIBWidth = jcprops.JPGWidth;
  jcprops.DIBHeight = jcprops.JPGHeight;
  // int nPad = IJL_DIB_PAD_BYTES(dwWidth,3)
  jcprops.DIBPadBytes = nPad;
  jcprops.DIBBytes = lpDstBuffer;

  // Now get the actual JPEG image data into the pixel buffer.
  jerr = ijlRead2(&jcprops, IJL_JBUFF_READWHOLEIMAGE);
  if(IJL_OK != jerr)
  {
   return FALSE;
  }

  bmpWidth = jcprops.DIBWidth;
  bmpHeight= jcprops.DIBHeight;
 } // __try
 //__finally
 //{
  // Clean up the Intel(R) JPEG Library.
  ijlFree2(&jcprops);
  *lpdwWidth = jcprops.DIBWidth;
  *lpdwHeight = jcprops.DIBHeight;
  *lpBits = jcprops.DIBChannels * 3;
  *dwDstSize = dwWholeImageSize;
  //*dwReserve1 = jcprops.DIBPadBytes;
 //} // __finally

 return bres;
}


int _tmain(int argc, _TCHAR* argv[])
{
 int g_cnBufferSize = 6*1024*1024;
 BYTE* lpDstBuffer = new BYTE[g_cnBufferSize];
 ZeroMemory(lpDstBuffer, g_cnBufferSize);

 DWORD dwDstSize = 0,dwWidth = 0,dwHeight = 0,dwBits = 0;


 BYTE*g_lpSrcBuffer = new BYTE[g_cnBufferSize];
 ZeroMemory(g_lpSrcBuffer, g_cnBufferSize);

 BYTE* g_lpSrcBuffer2 = new BYTE[g_cnBufferSize];
 ZeroMemory(g_lpSrcBuffer2, g_cnBufferSize);

 ifstream ifs;
 ifs.open("e:\testBmp\16671.jpg", ios::binary);
 ifs.read((char*)g_lpSrcBuffer, g_cnBufferSize);
 DWORD g_dwSrcSize = ifs.gcount();
 memcpy(g_lpSrcBuffer2, g_lpSrcBuffer, g_cnBufferSize);
 DWORD iIndex = 0;
 JpgDecode(g_lpSrcBuffer, g_dwSrcSize,lpDstBuffer, &dwDstSize,&dwWidth, &dwHeight, &dwBits, &iIndex);

 saveIjlBmp(lpDstBuffer,dwDstSize);
 readBmp("e:\testBmp\111.bmp");
 if (!HistogramEqualize())
 {
  cout << "HistogramEqualize error" << endl;
 }
 saveBmp();

 delete []lpDstBuffer;
 delete []g_lpSrcBuffer;
 delete []g_lpSrcBuffer2;
 lpDstBuffer = NULL;
 g_lpSrcBuffer = NULL;
 g_lpSrcBuffer2= NULL;

 int iNum;
 cin >> iNum;
 return 0;
}

0 0
原创粉丝点击