将图像转换为1位位图 (1像素对应1bit)

文章参考网址:http://www.voidcn.com/blog/suifeng50/article/p-4907477.html


#include "opencv2\highgui\highgui.hpp"

#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\core\core.hpp"
#include <Windows.h>
 #include<fstream>
#include<iostream>
#include <ctime>
using namespace cv;
using namespace std;


int  mat_to_binary( const  cv::Mat img,  int  line_byte,  char * data)
{
int  width = img.cols;
int  height = img.rows;
size_t  line_size = line_byte * 8;
size_t  bit_size = line_size * height;


char  *p = data;  int  offset, v; unsigned  char  temp;
for ( int  row=height-1; row>=0; row-- ) {       
for  ( int  col=0; col<width; col++ ) {  
offset = col % 8;
v = img.at<uchar>(row, col);
temp = 1;
temp = temp << (8 - offset -1);
if (v == 255 ) {                
*(p + col/8) |= temp;
}  else  {
temp = ~temp;
*(p + col/8) &= temp;
}
}
for ( int  j = width/8 ; j < line_byte; j++)
p[j] = 0;
p = p + line_byte;
}
return  0;
}


int  save_bmp_image( const  cv::Mat img, std::string dst) 
{
int  width = img.cols;
int  height = img.rows;
const  int  biBitCount = 1;


//颜色表大小,以字节为单位,灰度图像颜色表为256*4字节,彩色图像颜色表大小为0,二值图为2*4
int  color_type_num = 2;
int  colorTablesize = color_type_num *  sizeof (RGBQUAD);
RGBQUAD *pColorTable =  new  RGBQUAD[color_type_num];
for ( int  i = 0; i < color_type_num; i++) {
pColorTable[i].rgbBlue = i*255;
pColorTable[i].rgbRed  = i*255;
pColorTable[i].rgbGreen= i*255;
pColorTable[i].rgbReserved = 0;
}


//待存储图像数据每行字节数为4的倍数
int  line_byte = (width * biBitCount/8+3)/4*4;
char * p_data = ( char *) malloc (line_byte*height);
mat_to_binary(img, line_byte, p_data);


std::ofstream fp(dst.c_str(), std::ios::binary | std::ios::out);


if (!fp.is_open()) {
// cout <<  "open "  << dst << " failed!"  << endl;
return  -1;
}


//申请位图文件头结构变量,填写文件头信息
BITMAPFILEHEADER fileHead;
fileHead.bfType = 0x4D42;   //bmp类型


fileHead.bfSize=  sizeof (BITMAPFILEHEADER) +  sizeof (BITMAPINFOHEADER)\
+ colorTablesize + line_byte*height;               //bfSize是图像文件4个组成部分之和
fileHead.bfReserved1 = 0;
fileHead.bfReserved2 = 0;    
fileHead.bfOffBits = 54+colorTablesize;               //bfOffBits是图像文件前3个部分所需空间之和    


fp.write(( char *)&fileHead,  sizeof (BITMAPFILEHEADER)); //写文件头进文件


//申请位图信息头结构变量,填写信息头信息
BITMAPINFOHEADER head; 
head.biBitCount = biBitCount;
head.biClrImportant = 0;
head.biClrUsed = 0;
head.biCompression = 0;
head.biHeight = height;
head.biPlanes = 1;
head.biSize = 40;
head.biSizeImage = line_byte*height;
head.biWidth = width;
head.biXPelsPerMeter = 0;
head.biYPelsPerMeter = 0;


//写位图信息头进内存  
fp.write(( char *)&head,  sizeof (BITMAPINFOHEADER));


//颜色表,写入文件 
fp.write(( char *)pColorTable,  sizeof (RGBQUAD)*color_type_num);  


//写位图数据进文件pBmpBuf
fp.write(( char *)p_data, height*line_byte);
fp.close();


delete  []pColorTable;
delete  []p_data;
return  0;
}


int main()
{


clock_t start,finish;  
start=clock();  
//cout << "HW .... " << endl;  
 
Mat src=imread("E:\\Image\\0_1.bmp",0);//加载图像
   
string dst="E:\\Image\\2.bmp";//存放生成1位位图的路径


int a;
 




a=save_bmp_image( src, dst) ;
finish=clock(); 
cout << finish-start   << "/" << CLOCKS_PER_SEC  << " (s) "<< endl;  

cout <<a<<endl;
cout <<dst<<endl;








}



  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 以下是MFC中将24位图转换成1位图的代码实现: 1. 首先,需要打开24位图像文件,并将其加载到内存中。可以使用CImage类来实现这个过程: CImage img; img.Load(_T("24bit.bmp")); 2. 然后,需要创建一个新的1位图,并将其大小设置为与原始图像相同。可以使用CBitmap和CDC类来实现这个过程: CBitmap bmp; bmp.CreateBitmap(img.GetWidth(), img.GetHeight(), 1, 1, NULL); CDC memDC; memDC.CreateCompatibleDC(NULL); memDC.SelectObject(&bmp); 3. 接下来,需要将原始图像的每个像素转换为黑白像素,并将其写入新的1位图中: for (int y = 0; y < img.GetHeight(); y++) { for (int x = 0; x < img.GetWidth(); x++) { COLORREF pixel = img.GetPixel(x, y); int r = GetRValue(pixel); int g = GetGValue(pixel); int b = GetBValue(pixel); int gray = (r + g + b) / 3; if (gray < 128) { memDC.SetPixel(x, y, RGB(0, 0, 0)); } else { memDC.SetPixel(x, y, RGB(255, 255, 255)); } } } 4. 最后,需要将转换后的1位图保存到文件中: CImageConverter converter; converter.SaveBitmapToFile(bmp, _T("1bit.bmp"), _T("BMP")); 完整的代码如下: CImage img; img.Load(_T("24bit.bmp")); CBitmap bmp; bmp.CreateBitmap(img.GetWidth(), img.GetHeight(), 1, 1, NULL); CDC memDC; memDC.CreateCompatibleDC(NULL); memDC.SelectObject(&bmp); for (int y = 0; y < img.GetHeight(); y++) { for (int x = 0; x < img.GetWidth(); x++) { COLORREF pixel = img.GetPixel(x, y); int r = GetRValue(pixel); int g = GetGValue(pixel); int b = GetBValue(pixel); int gray = (r + g + b) / 3; if (gray < 128) { memDC.SetPixel(x, y, RGB(0, 0, 0)); } else { memDC.SetPixel(x, y, RGB(255, 255, 255)); } } } CImageConverter converter; converter.SaveBitmapToFile(bmp, _T("1bit.bmp"), _T("BMP")); ### 回答2: MFC提供了一种简单的方法将24位图转换为1位图,可以通过使用CImage类和相关函数来实现。下面是一个示例代码: ```cpp // 加载24位图像 CImage img; img.Load(_T("24bit_image.bmp")); // 获取图像宽度和高度 int width = img.GetWidth(); int height = img.GetHeight(); // 创建1位图 CImage img1bit; img1bit.Create(width, height, 1); HBITMAP hBitmap1bit = img1bit; CDC* pDC = CDC::FromHandle(img1bit.GetDC()); // 对每个像素进行转换 for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // 获取像素的RGB值 RGBQUAD color; img.GetPixel(x, y, &color); // 将RGB值转换为灰度值 int gray = (color.rgbRed + color.rgbGreen + color.rgbBlue) / 3; // 如果灰度值大于128,则设置像素为白色;否则设置为黑色 if (gray > 128) { pDC->SetPixel(x, y, RGB(255, 255, 255)); // 白色 } else { pDC->SetPixel(x, y, RGB(0, 0, 0)); // 黑色 } } } // 保存1位图到文件 img1bit.Save(_T("1bit_image.bmp")); img1bit.ReleaseDC(); ``` 以上代码首先使用CImage类加载24位图像。然后创建一个与原图像具有相同宽度和高度的1位图。接下来对每个像素进行遍历,将其RGB值转换为灰度值,然后根据灰度值设置对应像素为黑色或白色。最后,保存1位图到文件。 ### 回答3: MFC是一个用于开发Windows图形用户界面应用程序的框架。要将24位图转换为1位图,可以使用MFC中的GDI+图形库来实现。以下是实现该功能的代码示例: 1. 首先,需要包含必要的MFC头文件和命名空间: ``` #include <afxwin.h> using namespace Gdiplus; ``` 2. 创建一个MFC对话框应用程序,并在对话框类的头文件中添加下面的声明: ``` class CMyDialog : public CDialog { protected: virtual void DoDataExchange(CDataExchange* pDX); DECLARE_MESSAGE_MAP() // 存储24位图和1位图的变量 CImage m_img24bit; CImage m_img1bit; }; ``` 3. 在对话框类的实现文件中,添加下面的代码来实现图像转换: ``` void CMyDialog::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_PICTURE, m_picture); // IDC_PICTURE是对话框上的图片框控件的ID } void CMyDialog::OnButtonConvert() { // 加载24位图 m_img24bit.Load(_T("24bit.bmp")); // 24bit.bmp是要转换的24位图文件路径 // 创建1位图 m_img1bit.Create(24, 24, 1); // 创建一个24x24像素的1位图 // 获取24位图位图数据 BYTE* pBits24bit = (BYTE*)m_img24bit.GetBits(); // 获取1位图位图数据 BYTE* pBits1bit = (BYTE*)m_img1bit.GetBits(); // 将24位图转换为1位图 for(int i = 0; i < 24 * 24; i++) { // 分别获取24位图中每个像素点的RGB值 BYTE r = pBits24bit[3 * i + 2]; BYTE g = pBits24bit[3 * i + 1]; BYTE b = pBits24bit[3 * i]; // 计算1位图中每个像素点的索引 int index = (r + g + b) > 383 ? 1 : 0; // 设置1位图中每个像素点的值 pBits1bit[i] = index; } // 显示1位图 m_picture.SetBitmap((HBITMAP)m_img1bit.GetSafeHandle(), CxImage::CBORROW); // 保存1位图到文件 m_img1bit.Save(_T("1bit.bmp")); // 1bit.bmp是转换后的1位图文件路径 } ``` 以上代码示例假设24位图和1位图的尺寸都是24x24像素。在实际使用时,请根据具体需求进行调整。同时,请注意替换代码中的文件路径和控件ID,以适应实际情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值