原文作者:aircraft

原文地址:https://www.cnblogs.com/DOMLX/p/9598974.html

        我看了一下发现关于c++下的CImage图像处理类 的图像处理相关的介绍真的是比较少,因为我要做大二的数据结构的课程设计,要用纯c++语言去实现(老师不让调用opencv之类图像处理库),所以自己就尝试写了很多操作处理的代码,下面都是我课设用到的代码段,我已经降低耦合度分离出来了,并且全部都是用指针对内存的操作,这样速度比较快,现在就全部分享出来吧。

前人栽树,后人乘凉

望与诸君共勉。

        MFC图像处理CImage类常用操作

CImage类头文件为#include<atlimage.h>

CImage类读取图片CImage.Load("src.bmp");

CImage类保存图片CImage.Save("dst.jpg");

一.CImage类实例拷贝数据到另外一个CImage类实例

  1. bool ImageCopy(const CImage &srcImage, CImage &destImage)
  2. {
  3. int i, j;//循环变量
  4. if (srcImage.IsNull())
  5. return FALSE;
  6. //源图像参数
  7. BYTE* srcPtr = (BYTE*)srcImage.GetBits();
  8. int srcBitsCount = srcImage.GetBPP();
  9. int srcWidth = srcImage.GetWidth();
  10. int srcHeight = srcImage.GetHeight();
  11. int srcPitch = srcImage.GetPitch();
  12. //销毁原有图像
  13. if (!destImage.IsNull())
  14. {
  15. destImage.Destroy();
  16. }
  17. //创建CImage类新图像并分配内存
  18. if (srcBitsCount == ) //支持alpha通道
  19. {
  20. destImage.Create(srcWidth, srcHeight, srcBitsCount, );
  21. }
  22. else
  23. {
  24. destImage.Create(srcWidth, srcHeight, srcBitsCount, );
  25. }
  26. //加载调色板
  27. if (srcBitsCount <= && srcImage.IsIndexed())//需要调色板
  28. {
  29. RGBQUAD pal[];
  30. int nColors = srcImage.GetMaxColorTableEntries();
  31. if (nColors>)
  32. {
  33. srcImage.GetColorTable(, nColors, pal);
  34. destImage.SetColorTable(, nColors, pal);//复制调色板程序
  35. }
  36. }
  37. //目标图像参数
  38. BYTE *destPtr = (BYTE*)destImage.GetBits();
  39. int destPitch = destImage.GetPitch();
  40. //复制图像数据
  41. for (i = ; i<srcHeight; i++)
  42. {
  43. memcpy(destPtr + i*destPitch, srcPtr + i*srcPitch, abs(srcPitch));
  44. }
  45.  
  46. return TRUE;
  47. }

二.CImage类实例处理图像间的腐蚀运算

  1. //腐蚀运算
  1. //width:图像宽;height:图像高;矩形掩膜的边长(2*r+1)void erosion(CImage image, int width, int height, int r)
  2. {
  3. int i, j, m, n;
  4. int flag;
  5. //unsigned char * pBuff = tempBuff;
  6. CImage Buff;
  7. ImageCopy(image, Buff);
  8. //dataCopy(image, pBuff, width, height);
  9. byte *pImg = (byte *)image.GetBits();
  10. byte *pBuff = (byte *)Buff.GetBits();
  11. int step = image.GetPitch();
  12. //int height = image.GetHeight();
  13. //int width = image.GetWidth();
  14. for (i = r; i<height - r; i++)
  15. {
  16. for (j = r; j<width - r; j++)
  17. {
  18. flag = ;
  19. for (m = i - r; m <= i + r; m++)
  20. {
  21. for (n = j - r; n <= j + r; n++)
  22. {
  23. //if (!pBuff[i*width + j] || !pBuff[m*width + n])
  24. if (!*(pBuff + i*step + j) || !*(pBuff + m*step + n))
  25. {
  26. flag = ;
  27. break;
  28. }
  29. }
  30. }
  31. if (flag == )
  32. {
  33. *(pImg + i*step + j) = ;
  34. }
  35. else
  36. {
  37. *(pImg + i*step + j) = ;
  38. }
  39. }
  40. }
  41. }

三.CImage类实例处理图像间的膨胀运算

  1. //膨胀运算
  2. //width:图像宽;height:图像高;矩形掩膜的边长(2*r+1)
  3. void diate(CImage image, int width, int height, int r)
  4. {
  5. int i, j, m, n;
  6. int flag;
  7. //unsigned char * pBuff = tempBuff;
  8.  
  9. CImage Buff;
  10. ImageCopy(image, Buff);
  11. //dataCopy(image, pBuff, width, height);
  12. byte *pImg = (byte *)image.GetBits();
  13. byte *pBuff = (byte *)Buff.GetBits();
  14. int step = image.GetPitch();
  15. //int height = image.GetHeight();
  16. //int width = image.GetWidth();
  17. //dataCopy(image, pBuff, width, height);
  18. for (i = r; i<height - r; i++)
  19. {
  20. for (j = r; j<width - r; j++)
  21. {
  22. flag = ;
  23. for (m = i - r; m <= i + r; m++)
  24. {
  25. for (n = j - r; n <= j + r; n++)
  26. {
  27. if ( == *(pBuff + i*step + j) || == *(pBuff + m*step + n))
  28. {
  29. flag = ;
  30. break;
  31. }
  32. }
  33. }
  34. if (flag == )
  35. {
  36. *(pImg + i*step + j) = ;
  37. }
  38. else
  39. {
  40. *(pImg + i*step + j) = ;
  41. }
  42. }
  43. }
  44. }

四.CImage类实例处理图片遍历赋值操作

  1. byte *pImg = (byte *)imgSrc.GetBits();
  2. int step = imgSrc.GetPitch();
  3. int height = imgSrc.GetHeight();
  4. int width = imgSrc.GetWidth();
  5. int sum = ;
  6. unsigned char val = ;
  7. //初始化
  8. for (int i = ; i<maxY; i++)
  9. for (int j = ; j<maxX; j++)
  10. *(pDstImg + i*step + j) = ;

五.用CImage类实例遍历生成手指静脉边缘图

  1. #define mlen 9 //模板长度
  2. //加长扩展的水平边缘检测模板
  3. int upperEdgeOperator[mlen * ] =
  4. {
  5. -, -, -, -, -, -, -, -, -,
  6. , , , , , , , , ,
  7. , , , , , , , ,
  8. };
  9. int lowerEdgeOperator[mlen * ] =
  10. {
  11. , , , , , , , , ,
  12. , , , , , , , , ,
  13. -, -, -, -, -, -, -, -, -
  14. };
  15.  
  16. int findEdgesHorizontal(CImage& imgSrc, CImage& imgDst)
  17. {
  18. int maxY = imgSrc.GetHeight();
  19. int maxX = imgSrc.GetWidth();
  20.  
  21. if (!imgDst.IsNull())
  22. {
  23. imgDst.Destroy();
  24. }
  25. imgDst.Create(maxX, maxY, , );//图像大小与imgSrc相同,每个像素占1字节
  26.  
  27. if (imgDst.IsNull())
  28. return FALSE;
  29.  
  30. byte *pImg = (byte *)imgSrc.GetBits();
  31. byte *pDstImg = (byte *)imgDst.GetBits();
  32. int step = imgSrc.GetPitch();
  33. int height = imgSrc.GetHeight();
  34. int width = imgSrc.GetWidth();
  35. int sum = ;
  36. unsigned char val = ;
  37. //初始化
  38. for (int i = ; i<maxY; i++)
  39. for (int j = ; j<maxX; j++)
  40. *(pDstImg + i*step + j) = ;
  41.  
  42. //找上边缘
  43. for (int i = ; i <maxY / - ; i++)
  44. {
  45. for (int j = ; j < maxX - ; j++)
  46. {
  47. sum = ;
  48. for (int m = -; m <= ; m++)
  49. {
  50. for (int n = -mlen / ; n <= mlen / ; n++)
  51. {
  52. sum += *(pImg + (i + m)*step + (j + n))*upperEdgeOperator[(m + )*mlen + (n + mlen / )];
  53. }
  54. }
  55. sum = sum < ? : sum;
  56. sum = sum > ? : sum;
  57. val = unsigned char(sum);
  58. *(pDstImg + i*step + j) = val;
  59. }
  60. }
  61. //找下边缘
  62. for (int i = maxY / + ; i <maxY - ; i++)
  63. {
  64. for (int j = ; j < maxX - ; j++)
  65. {
  66. sum = ;
  67. for (int m = -; m <= ; m++)
  68. {
  69. for (int n = -mlen / ; n <= mlen / ; n++)
  70. {
  71. sum += *(pImg + (i + m)*step + (j + n))*upperEdgeOperator[(m + )*mlen + (n + mlen / )];;
  72. }
  73. }
  74. sum = sum < ? : sum;
  75. sum = sum > ? : sum;
  76. val = unsigned char(sum);
  77. *(pDstImg + i*step + j) = val;
  78. }
  79. }
  80.  
  81. return TRUE;
  82. }

六.CImage图像类实例将RGB图转为灰度(gary)图

  1. BOOL ImageToGray(CImage& imgSrc, CImage& imgDst)
  2. {
  3. int maxY = imgSrc.GetHeight();
  4. int maxX = imgSrc.GetWidth();
  5.  
  6. if (!imgDst.IsNull())
  7. {
  8. imgDst.Destroy();
  9. }
  10. imgDst.Create(maxX, maxY, , );//图像大小与imgSrc相同,每个像素占1字节
  11.  
  12. if (imgDst.IsNull())
  13. return FALSE;
  14.  
  15. //为imgDst构造256阶灰度调色表
  16. RGBQUAD ColorTab[];
  17. for (int i = ; i<; i++)
  18. {
  19. ColorTab[i].rgbBlue = ColorTab[i].rgbGreen = ColorTab[i].rgbRed = i;
  20. }
  21. imgDst.SetColorTable(, , ColorTab);
  22.  
  23. byte* pDataSrc = (byte*)imgSrc.GetBits(); //获取指向图像数据的指针
  24. byte* pDataDst = (byte*)imgDst.GetBits();
  25. int pitchSrc = imgSrc.GetPitch(); //获取每行图像占用的字节数 +:top-down;-:bottom-up DIB
  26. int pitchDst = imgDst.GetPitch();
  27. int bitCountSrc = imgSrc.GetBPP() / ; // 获取每个像素占用的字节数
  28. int bitCountDst = imgDst.GetBPP() / ;
  29. if ((bitCountSrc != ) || (bitCountDst != ))
  30. return FALSE;
  31. int tmpR, tmpG, tmpB, avg;
  32. for (int i = ; i<maxX; i++)
  33. {
  34. for (int j = ; j<maxY; j++)
  35. {
  36. tmpR = *(pDataSrc + pitchSrc*j + i*bitCountSrc);
  37. tmpG = *(pDataSrc + pitchSrc*j + i*bitCountSrc + );
  38. tmpB = *(pDataSrc + pitchSrc*j + i*bitCountSrc + );
  39. avg = (int)(tmpR + tmpG + tmpB) / ;
  40. *(pDataDst + pitchDst*j + i*bitCountDst) = avg;
  41. }
  42. }
  43. return TRUE;
  44. }

七.CImage类转opencv Mat类  以及Mat类转CImage类

  1. #include "stdafx.h"
  2. #include <opencv2/opencv.hpp>
  3. #include "CimgMat.h"
  4.  
  5. void CimgMat::MatToCImage(Mat& mat, CImage& cimage)
  6. {
  7. if ( == mat.total())
  8. {
  9. return;
  10. }
  11.  
  12. int nChannels = mat.channels();
  13. if (( != nChannels) && ( != nChannels))
  14. {
  15. return;
  16. }
  17. int nWidth = mat.cols;
  18. int nHeight = mat.rows;
  19.  
  20. //重建cimage
  21. cimage.Destroy();
  22. cimage.Create(nWidth, nHeight, * nChannels);
  23.  
  24. //拷贝数据
  25.  
  26. uchar* pucRow; //指向数据区的行指针
  27. uchar* pucImage = (uchar*)cimage.GetBits(); //指向数据区的指针
  28. int nStep = cimage.GetPitch(); //每行的字节数,注意这个返回值有正有负
  29.  
  30. if ( == nChannels) //对于单通道的图像需要初始化调色板
  31. {
  32. RGBQUAD* rgbquadColorTable;
  33. int nMaxColors = ;
  34. rgbquadColorTable = new RGBQUAD[nMaxColors];
  35. cimage.GetColorTable(, nMaxColors, rgbquadColorTable);
  36. for (int nColor = ; nColor < nMaxColors; nColor++)
  37. {
  38. rgbquadColorTable[nColor].rgbBlue = (uchar)nColor;
  39. rgbquadColorTable[nColor].rgbGreen = (uchar)nColor;
  40. rgbquadColorTable[nColor].rgbRed = (uchar)nColor;
  41. }
  42. cimage.SetColorTable(, nMaxColors, rgbquadColorTable);
  43. delete[]rgbquadColorTable;
  44. }
  45.  
  46. for (int nRow = ; nRow < nHeight; nRow++)
  47. {
  48. pucRow = (mat.ptr<uchar>(nRow));
  49. for (int nCol = ; nCol < nWidth; nCol++)
  50. {
  51. if ( == nChannels)
  52. {
  53. *(pucImage + nRow * nStep + nCol) = pucRow[nCol];
  54. }
  55. else if ( == nChannels)
  56. {
  57. for (int nCha = ; nCha < ; nCha++)
  58. {
  59. *(pucImage + nRow * nStep + nCol * + nCha) = pucRow[nCol * + nCha];
  60. }
  61. }
  62. }
  63. }
  64. }
  65.  
  66. void CimgMat::CImageToMat(CImage& cimage, Mat& mat)
  67. {
  68. if (true == cimage.IsNull())
  69. {
  70. return;
  71. }
  72.  
  73. int nChannels = cimage.GetBPP() / ;
  74. if (( != nChannels) && ( != nChannels))
  75. {
  76. return;
  77. }
  78. int nWidth = cimage.GetWidth();
  79. int nHeight = cimage.GetHeight();
  80.  
  81. //重建mat
  82. if ( == nChannels)
  83. {
  84. mat.create(nHeight, nWidth, CV_8UC1);
  85. }
  86. else if ( == nChannels)
  87. {
  88. mat.create(nHeight, nWidth, CV_8UC3);
  89. }
  90.  
  91. //拷贝数据
  92.  
  93. uchar* pucRow; //指向数据区的行指针
  94. uchar* pucImage = (uchar*)cimage.GetBits(); //指向数据区的指针
  95. int nStep = cimage.GetPitch(); //每行的字节数,注意这个返回值有正有负
  96.  
  97. for (int nRow = ; nRow < nHeight; nRow++)
  98. {
  99. pucRow = (mat.ptr<uchar>(nRow));
  100. for (int nCol = ; nCol < nWidth; nCol++)
  101. {
  102. if ( == nChannels)
  103. {
  104. pucRow[nCol] = *(pucImage + nRow * nStep + nCol);
  105. }
  106. else if ( == nChannels)
  107. {
  108. for (int nCha = ; nCha < ; nCha++)
  109. {
  110. pucRow[nCol * + nCha] = *(pucImage + nRow * nStep + nCol * + nCha);
  111. }
  112. }
  113. }
  114. }
  115. }

八.纯图像数据赋值给CImage后的初始化,并且写入调色板

  1. bool InitalImage(CImage &image, int width, int height)
  2. {
  3. if (image.IsNull())
  4. image.Create(width, height, );
  5. else
  6. {
  7. if (width <= || height <= )
  8. return false;
  9. else if (image.GetHeight() == width && image.GetWidth() == height)
  10. return true;
  11. else
  12. {
  13. image.Destroy();
  14. image.Create(width, height, );
  15. }
  16. }
  17. //写入调色板
  18. RGBQUAD ColorTable[];
  19. image.GetColorTable(, , ColorTable);
  20. for (int i = ; i < ; i++)
  21. {
  22. ColorTable[i].rgbBlue = (BYTE)i;
  23. ColorTable[i].rgbGreen = (BYTE)i;
  24. ColorTable[i].rgbRed = (BYTE)i;
  25. }
  26. image.SetColorTable(, , ColorTable);
  27. return true;
  28. }

九.根据MFC控件大小CImage类实例图片显示

  1. if(m_image2.IsNull()) //判断有无图像
  2. return;
  3.  
  4. // 取得客户区尺寸
  5. CRect zcRect;
  6. GetDlgItem(IDC_STATIC_PIC2)->GetClientRect(&zcRect);
  7.  
  8. // 将图像显示在界面之上
  9. m_image2.Draw(GetDlgItem(IDC_STATIC_PIC2)->GetDC()->m_hDC,
  10. zcRect.left,
  11. zcRect.top,
  12. zcRect.Width(),
  13. zcRect.Height());

十.根据CImage类实例图片调整控件大小显示图片

  1. if(m_image1.IsNull())
  2. return;
  3.  
  4. // 将整控件调整为与图像同一尺寸
  5. GetDlgItem(IDC_STATIC_PIC)->SetWindowPos(NULL,
  6. 0,0,m_image1.GetWidth(), m_image1.GetHeight(),
  7. SWP_NOMOVE);
  8.  
  9. CRect zcRect;
  10. GetDlgItem(IDC_STATIC_PIC)->GetClientRect(&zcRect);
  11.  
  12. m_image1.Draw(GetDlgItem(IDC_STATIC_PIC)->GetDC()->m_hDC,
  13. zcRect.left,
  14. zcRect.top,
  15. zcRect.Width(),
  16. zcRect.Height());

十一.CImage类与CBitmap转换

  1. CImage nImage;
  2. nImage.Load(imgFilePath);
  3.  
  4. HBITMAP hBitmap=nImage.Detach(); // 获得位图句柄 用以转换
  5.  
  6. // 转换方式一:
  7. CBitmap bmp;
  8. bmp.DeleteObject();
  9. bmp.Attach(hBitmap); // 转换为CBitmap对象
  10.  
  11. // 转换方式二:
  12.  
  13. CBitmap *pBitmap=CBitmap::FromHandle(nImage.m_hBitmap);

十二.CImage类实例实现图像二值化

  1. void imgBinary(CImage image, int imgW, int imgH, int threshold)
  2. {
  3. int i;
  4. int index = ;
  5. byte *pImg = (byte *)image.GetBits();
  6. int step = image.GetPitch();
  7. int height = image.GetHeight();
  8. int width = image.GetWidth();
  9. for (i = ; i<height*width; i++)
  10. {
  11. *(pImg + index) = *(pImg + index)>threshold ? : ;
  12. index++;
  13. }
  14.  
  15. }

十三.CImage实现自己的argmax函数----求图像一定高度区域中某一列遇到的第一个最大像素值的坐标并返回

  1. int argmax(CImage &image,int Top,int Bottom,int x)
  2. {
  3. int max = ;
  4. int tem;
  5. int pos = ;
  6. byte *pImg = (byte *)image.GetBits();
  7. int step = image.GetPitch();
  8. int height = image.GetHeight();
  9. int width = image.GetWidth();
  10. if (Top > && Top < height && Bottom > && Bottom < height && x > && x < width)
  11. {
  12. for (int i = Top; i < Bottom; ++i)
  13. {
  14. tem = *(pImg + i*step + x);
  15. if (tem > max)
  16. {
  17. max = tem;
  18. pos = i;
  19. }
  20.  
  21. }
  22. return pos;
  23. }
  24. else
  25. {
  26. return FALSE;
  27. }
  28.  
  29. }

十四.CImage类创建指定长宽图像并初始化调色板

  1. bool InitalImage(CImage &image, int width, int height)
  2. {
  3. if (image.IsNull())
  4. image.Create(width, height, );
  5. else
  6. {
  7. if (width <= || height <= )
  8. return false;
  9. else if (image.GetHeight() == width && image.GetWidth() == height)
  10. return true;
  11. else
  12. {
  13. image.Destroy();
  14. image.Create(width, height, );
  15. }
  16. }
  17. //写入调色板
  18. RGBQUAD ColorTable[];
  19. image.GetColorTable(, , ColorTable);
  20. for (int i = ; i < ; i++)
  21. {
  22. ColorTable[i].rgbBlue = (BYTE)i;
  23. ColorTable[i].rgbGreen = (BYTE)i;
  24. ColorTable[i].rgbRed = (BYTE)i;
  25. }
  26. image.SetColorTable(, , ColorTable);
  27. return true;
  28. }

十五.将存放在一维指针数组里的图像数据赋值给CImage类实例

  1. void LoadImageData(CImage &image, unsigned char * data)
  2. {
  3. if (data == nullptr)
  4. return;
  5. byte *pS;
  6. byte *pImg = (byte *)image.GetBits();
  7. int step = image.GetPitch();
  8. int height = image.GetHeight();
  9. int width = image.GetWidth();
  10. for (int i = ; i < image.GetHeight(); ++i)
  11. {
  12. pS = data + i * width;
  13. for (int j = ; j < image.GetWidth(); ++j)
  14. {
  15. *(pImg + i*step + j) = pS[j];
  16. }
  17. }
  18. }

十六.CImage类自己实现图片的裁剪

  1. //裁剪roi区域
  2. void RoiCut(CImage &image, CImage &roiImg, int heightTop,int heightDown,int widthBegin,int widthEnd)
  3. {
  4. InitalImage(roiImg, heightDown - heightTop + , widthBegin - widthEnd + );
  5. byte *pImg = (byte *)image.GetBits();
  6. byte *pRoi = (byte *)roiImg.GetBits();
  7. int step = image.GetPitch();
  8. int height = image.GetHeight();
  9. int width = image.GetWidth();
  10. int index = ;
  11. for (int i = heightTop; i < heightDown; i++)
  12. {
  13. for (int j = widthBegin; j < widthEnd; j++)
  14. {
  15. *(pRoi + index) = *(pImg + i*step + j);
  16. index++;
  17. }
  18. }
  19.  
  20. }

十七.CImage类截取电脑屏幕图片,也就是屏幕截图的意思

  1. #include"iostream"
  2. #include<atlimage.h>
  3.  
  4. int main()
  5. {
  6. HDC hDCScreen = ::GetDC(NULL);//首先获取到屏幕的句柄
  7. int nBitPerPixel = GetDeviceCaps(hDCScreen, BITSPIXEL);//获取到每个像素的bit数目
  8. int nWidthScreen = GetDeviceCaps(hDCScreen, HORZRES);
  9. int nHeightScreen = GetDeviceCaps(hDCScreen, VERTRES);
  10. //创建一个CImage的对象
  11. CImage m_MyImage;
  12. //Create实例化CImage,使得其内部的画布大小与屏幕一致
  13. m_MyImage.Create(nWidthScreen, nHeightScreen, nBitPerPixel);
  14. //获取到CImage的 HDC,但是需要手动ReleaseDC操作,下面是MSDN的说明
  15. //Because only one bitmap can be selected into a device context at a time,
  16. //you must call ReleaseDC for each call to GetDC.
  17. HDC hDCImg = m_MyImage.GetDC();
  18.  
  19. //使用bitblt 将屏幕的DC画布上的内容 拷贝到CImage上
  20. BitBlt(hDCImg, , , nWidthScreen, nHeightScreen, hDCScreen, , , SRCCOPY);
  21.  
  22. //直接保存吧
  23. m_MyImage.Save("C:\\test.bmp", Gdiplus::ImageFormatBMP);
  24. m_MyImage.Save("C:\\test.png", Gdiplus::ImageFormatPNG);
  25. m_MyImage.Save("C:\\test.jpeg", Gdiplus::ImageFormatJPEG);
  26.  
  27. //前面调用了GetDC所以需要调用ReleaseDC释放掉
  28. //详情请参见MSDN
  29. m_MyImage.ReleaseDC();
  30. return ;
  31. }

十八.CImage转为CBitmap以及CBitmap转CImage

  1. #include<atlimage.h>
  2. #include<afxwin.h>
  3.  
  4. void cimageToCbitmap(CImage & srcImg, CBitmap & dstImg)
  5. {
  6.  
  7. HBITMAP hbmp = (HBITMAP)srcImg.operator HBITMAP();
  8.  
  9. dstImg.DeleteObject();
  10.  
  11. dstImg.Attach(hbmp);
  12. }
  13.  
  14. void cbitmapToCimage(CBitmap & srcImg, CImage & dstImg)
  15. {
  16. HBITMAP hbmp = (HBITMAP)srcImg.GetSafeHandle();
  17.  
  18. if (!dstImg.IsNull()) //Attach前,必须确认img中无位图,否则会弹出异常,但忽略也可继续运行
  19. dstImg.Destroy();
  20.  
  21. dstImg.Attach(hbmp);
  22.  
  23. //另注:原对象中的位图改变后,所有Attach到这个对象的对象需从新Attach一次,否则图像为初始化的颜色或黑色!
  24. }

十八.CImage类实现图形旋转90度(通过计算旋转矩阵之后的位置直接映射过去)

  1. CImage * srcImg = new CImage();
  2.  
  3. srcImg->Load(strPicName);
  4. BYTE* srcPtr = (BYTE*)srcImg->GetBits();
  5. int srcBitsCount = srcImg->GetBPP();
  6. int srcWidth = srcImg->GetWidth();
  7. int srcHeight = srcImg->GetHeight();
  8. int srcPitch = srcImg->GetPitch();
  9.  
  10. //删除原始图片
  11.  
  12. DeleteFile(strPicName);
  13.  
  14. //创建新图像
  15.  
  16. CImage * dstImg = new CImage();
  17. dstImg->Create(, , srcBitsCount, );
  18.  
  19. //加载调色板
  20. if (srcBitsCount <= && srcImg->IsIndexed())//需要调色板
  21. {
  22. RGBQUAD pal[];
  23. int nColors = srcImg->GetMaxColorTableEntries();
  24. if (nColors > )
  25. {
  26. srcImg->GetColorTable(, nColors, pal);
  27. dstImg->SetColorTable(, nColors, pal);//复制调色板程序
  28. }
  29. }
  30. //目标图像参数
  31. BYTE *destPtr = (BYTE*)dstImg->GetBits();
  32. int destPitch = dstImg->GetPitch();
  33. int width = dstImg->GetWidth();
  34. int height = dstImg->GetHeight();
  35. //复制图像数据
  36. for (int i = ; i < height; i++)
  37. {
  38. for (int j = ; j < width; j++)
  39.  
  40. {
  41.  
  42. ifsrcBitsCount ==
  43.  
  44. {
  45.  
  46. *(destPtr + ( - j)*destPitch + * i) = *(srcPtr + i * srcPitch + * j);//目的图片的第一列
  47. *(destPtr + ( - j)*destPitch + * i + ) = *(srcPtr + i * srcPitch + * j + );
  48.  
  49. *(destPtr + ( - j)*destPitch + * i + ) = *(srcPtr + i * srcPitch + * j + );
  50.  
  51. }
  52.  
  53. else ifsrcBitsCount ==
  54.  
  55. {
  56.  
  57. *(destPtr + ( - j)*destPitch + i) = *(srcPtr + i * srcPitch + j);//目的图片的第一列
  58.  
  59. }
  60.  
  61. }
  62. }
  63.  
  64. //保存新图像
  65. dstImg->Save(strPicName);
  66. delete srcImg;
  67. delete dstImg;

还有一些操作比较麻烦这里就先不写了,后面想到什么在写把嘿嘿。

参考博客:https://blog.csdn.net/ishallwin/article/details/4840180

参考博客:https://blog.csdn.net/shuilan0066/article/details/7080244

若有兴趣交流分享技术,可关注本人公众号,里面会不定期的分享各种编程教程,和共享源码,诸如研究分享关于c/c++,python,前端,后端,opencv,halcon,opengl,机器学习深度学习之类有关于基础编程,图像处理和机器视觉开发的知识

c++ MFC图像处理CImage类常用操作代码的更多相关文章

  1. legend3---lavarel常用操作代码

    legend3---lavarel常用操作代码 一.总结 一句话总结: 要自己总结一下常用代码,这样才方便,也才有收获 1.路由示例:Route::get('/login','Home\Login\L ...

  2. 使用matlab进行图像处理的一些常用操作和tip

    本人还是习惯使用Python语言,有时候不得不使用matlab的时候就变得举步维艰,下面记录一下使用matlab进行图像处理的一些常用操作以及代码,方便之后查阅: 1. 图像的读取 %% 读取原图像 ...

  3. legend3---lavarel常用操作代码2

    legend3---lavarel常用操作代码2 一.总结 一句话总结: 对于王思cong被执法人的感悟:失意时 莫心伤,得意时 莫膨胀 1.lavarel自动事务? DB::transaction方 ...

  4. legend3---Homestead常用操作代码

    legend3---Homestead常用操作代码 一.总结 一句话总结: 在虚拟机里面改变文件windows里面也会变,在windows里面改变虚拟机里面也会变,所以可以在windows里面编程或者 ...

  5. 二叉树的python可视化和常用操作代码

    二叉树是一个重要的数据结构, 本文基于"二叉查找树"的python可视化 pybst 包, 做了一些改造, 可以支持更一般的"二叉树"可视化. 关于二叉树和二叉 ...

  6. [Swift]字符串(String类、NSString类)常用操作

    NS是Cocoa类对象类型的前缀,来源于乔布斯建立的另一家公司--NeXTNSString的使用方法,和Swift语言中的String有很多相似之处. 1.字符串的定义String类 var str1 ...

  7. 【java】String类和StringBuffer类常用操作

    String类是字符串常量,是不可更改的常量.而StringBuffer是字符串变量,它的对象是可以扩充和修改的.StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于Stri ...

  8. js常用操作代码

    页面前进后退<input type=button value=刷新 onclick="window.location.reload()"><input type= ...

  9. C++字符串string类常用操作详解(一)【初始化、遍历、连接】

    代码示例: #include <iostream> #include "string" using namespace std; //字符串初始化 void strIn ...

随机推荐

  1. RobotFramework添加自定义关键字实战

    背景: 此篇文章是上一篇博客python的requests库怎么发送带cookies的请求的后续,上一篇只是使用python脚本调试通过了,接下来要把我们的方法封装为关键字,在RF中调用. 实施: 一 ...

  2. C# enum 枚举 反射

    枚举遍历 public enum EMyType { [System.ComponentModel.Description("A类型")] TypeA = 1, [System.C ...

  3. dynamic的好处

    dynamic 可在反射.json反序列化时使用.已达到减少代码量的效果.看代码 using System; namespace ConsoleApp2 { class Program { stati ...

  4. oracle查询分区表中的数据

    select * from TABLE_NAME partition(分区名) T WHERE T.COL_NAME= 'XX';

  5. ASPxGridView后台实现隐藏新增按钮

    (ASPxGridView2.Columns[0] as GridViewCommandColumn).NewButton.Visible = false;//0应该代表的是NewButton所在的列 ...

  6. 题解 P1534 【不高兴的津津(升级版)】

    题目链接 不算太难.就是题目有歧义. wa了好几次才发现.上一天要是小于8的话.结算是昨天一个负值在加上今天课时数.再减去8.233.... 而不是上一天小于8个小时.就清零了..大家要注意(ps:题 ...

  7. 「BZOJ1433」[ZJOI2009] 假期的宿舍(二分图,网络流)

    题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...

  8. 八大排序算法的python实现(六)归并排序

    代码: #coding:utf-8 #author:徐卜灵 def merge(left,right): i,j = 0,0 result = [] while i < len(left) an ...

  9. Python3用sys和time模块实现进度条

    import sys import time def view_bar(num, total): rate = float(num) / float(total) rate_num = int(rat ...

  10. ubuntu下安装谷歌浏览器

    deb 是 Debian Linux 的安装格式,在 ubuntu 中同样可以使用.要安装 deb 安装包,需要使用 dpkg这个终端命令,命令格式如下: $ sudo dpkg -i <pac ...