QT编程——图像基本处理

读取图片文件

void openfile()
{
	Qstring file_path='./';
	//目录路径显示
    QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("打开图片文件"),file_path,"JPG(*.jpg);;BMP(*.bmp);;PNG(*.png)");//过滤出图片文件
        if(fileNames.isEmpty())
            return;
    Qstring file_name=fileNames[0];

    if(imgsrc!=nullptr)//全局QImage指针
        delete imgsrc;
    imgsrc=new QImage(file_name);
    ui->qlabel->setPixmap(QPixmap::fromImage(*imgsrc));//在QLabel上显示图片
}

窗口自适应显示设置

可以设置一个 QCheckBox 进行自适应控制,信号和槽连接如下 。

connect(ui->checkBox,&QCheckBox::stateChanged, this, &zsyck);//窗口图片自适应

槽函数:

void ImgShow:: zsyck(int state)//窗口图片自适应
{

    if(state==Qt::Checked)//选中
    {
        ui->qlabel->setScaledContents(true);
    }
    else
    {
        ui->qlabel->setScaledContents(false);
    }

}

图片保存

void ImgShow::savefile()
{
    if(imgdst==nullptr)
        return;
    //目录路径显示
    Qstring file_name = QFileDialog::getSaveFileName(this, tr("保存图片文件"),file_path,"JPG(*.jpg);;BMP(*.bmp);;PNG(*.png)");//过滤出图片文件
    if(file_name.isNull())
            return;

    QDir dir(file_name);
    dir.cdUp();//上一级目录
    Qstring file_path=dir.path();//搜索路径更新

    int nIndex = file_name.lastIndexOf('.');//寻找‘.’符号在字符串中的id 位置
    int nLen = file_name.length()-(nIndex+1);
    QString strSuffix = file_name.right(nLen);//截取‘.’符号后面的字符串,这是为了获取用户选择的文件后缀名
    imgdst->save(file_name,strSuffix.toUpper().toUtf8());//保存图片
}

格式转换

QImage图片格式:

enum QImage::Format
QImage::Format_Invalid 图像无效
QImage::Format_Mono 存储使用1位每像素的图像,字节填充最重要位第一
QImage::Format_MonoLSB 存储使用1位每像素的图像,字节填充不显著位第一
QImage::Format_Indexed8 图像存储使用8位指标转化成Colormap
QImage::Format_RGB32 存储使用32位RGB格式的图像(0xffrrggbb)
QImage::Format_ARGB32 存储使用32为ARGB格式的图像(0xaarrggbb)
QImage::Format_ARGB32_Premultiplied 图像存储使用一个自左乘32位ARGB格式
QImage::Format_RGB16 图像存储使用5-6-5 16位RGB格式
QImage::Format_ARGB8565_Premultiplied 图像存储使用一个自左乘24位ARGB格式8-5-6-5
QImage::Format_RGB666 图像存储使用6-6-6 24位RGB格式,未使用的最重要的位总是为零
QImage::Format_ARGB6666_Premultiplied 图像存储使用一个自左乘24位ARGB格式6-6-6-6
QImage::Format_RGB555 图像存储使用16位RGB格式(5-5-5),位置用的最重要的始终为零
QImage::Format_ARGB8555_Premultiplied 图像存储使用一个自左乘24位ARGB格式8-5-5-5
QImage::Format_RGB888 图像存储使用8-8-8 24位RGB格式
QImage::Format_RGB444 图像存储使用16位RGB格式(4-4-4)未使用的位始终为零
QImage::Format_ARGB4444_Premultiplied 图像存储使用一个自左乘16位ARGB格式4-4-4-4
QImage::Format_RGBX8888 图像存储使用32位字节命令RGB(x)格式8-8-8-8
QImage::Format_RGBA8888 存储使用32位字节命令RGBA格式(8-8-8-8)的的图像
QImage::Format_RGBA8888_Premultiplied 图像存储使用一个自左乘32位字节命令RGBA格式8-8-8-8
QImage::Format_BGR30 存储使用32位BGR格式(x-10-10-10)的的图像
QImage::Format_A2BGR30_Premultiplied 图像存储使用32位自左乘abgr格式2-10-10-10
QImage::Format_RGB30 存储使用32位RGB格式(x-10-10-10)的的图像
QImage::Format_A2RGB30_Premultiplied 图像存储使用2-10-10-10 32位自左乘ARGB格式
QImage::Format_Alpha8 该图像是使用一个8位的阿尔法格式存储
QImage::Format_Grayscale8 图像是使用一个8位灰度格式存储

图像格式转换为RGB565或者灰度时,如下

void ImgShow::toRgb565()
{
    if(imgdst!=nullptr)
    {
        delete imgdst;
    }
    if(imgsrc!=nullptr)
    {
        imgdst= new QImage(imgsrc->convertToFormat(QImage::Format_RGB16));
        //显示
        QPixmap pix = QPixmap::fromImage(*imgdst);
        ui->qlabel->setPixmap(pix);
    }
}
void ImgShow::toGray()
{
    if(imgdst!=nullptr)
    {
        delete imgdst;
    }
    if(imgsrc!=nullptr)
    {
        imgdst=new QImage(imgsrc->convertToFormat(QImage::Format_Grayscale8));
        //显示
        QPixmap pix = QPixmap::fromImage(*imgdst);
        ui->qlabel->setPixmap(pix);
    }
}

读取像素转为hex文本

读取灰度图像时,白色为255,黑色为0:

void read_gray_image()
{
	if(imgdst->format()!=QImage::Format_Grayscale8)
		return;
	QByteArray Serial_buff;
	uchar * datap;
	for(int i=0;i<imgdst->height();i++)
	{
	    datap=imgdst->scanLine(i);
	    for(int j=0;j<imgdst->width();j++)
	    {
	        Serial_buff +=QString("0x%1,").arg(datap[j], 2, 16, QLatin1Char('0'));//16进制
	        gnnu
	        m++;
	        if(gnnum%20 == 0)
	            Serial_buff +="\n";
	    }
	}
}

在这里插入图片描述

unsigned char YMImg_data[400]={ // width= 20 height= 20 imgtype=gray
0x27,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
0xff,0x27,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,
0xff,0xff,0x27,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,
0xff,0xff,0xff,0x27,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0x27,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0x27,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x27,0xff,0xff,0xff,0x57,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x27,0xff,0xff,0x57,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x27,0xff,0x57,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x57,0x27,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0x57,0xff,0x27,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x57,0xff,0xff,0x27,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0x27,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0x27,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0xff,0x27,0xff,0xff,0xff,
0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0x27,0xff,0xff,
0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x27,0xff,
0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x27,
}

读取RGB565时,就得注意数据的大小端问题了,这里略提一下大小段问题:

比如说现在有一个unsigned short的数据值为0x0001
你现在用一个unsigned char 的指针p去访问
如果p[0]=0x00,p[1]=0x01,那么这个机器就是大端机器;
如果p[0]=0x01,p[1]=0x00,那么这个机器就是小端机器;

所以用unsigned char对rgb565的数据读取时要注意,直接这么读的话:

void read_rgb565_image()
{
	if(imgdst->format()!=QImage::Format_RGB16)
		return;
	QByteArray Serial_buff;
	uchar * datap;
	for(int i=0;i<imgdst->height();i++)
	{
	    datap=imgdst->scanLine(i);
	    for(int j=0;j<imgdst->width();j++)
	    {
	        Serial_buff +=QString("0x%1,0x%2,").arg(datap[2*j], 2, 16, QLatin1Char('0')).arg(datap[2*j+1], 2, 16, QLatin1Char('0'));//16进制
	        gnnu
	        m++;
	        if(gnnum%20 == 0)
	            Serial_buff +="\n";
	    }
	}
}

比如蓝色本来应该是0x001F绿色0x07E0红色应该是0xF800,但是如果小端机器,读取出来的数据就变成了这样:

蓝色 : 0x1F00绿色 :0xE007红色 : 0x00F8

unsigned char YMImg_data[800]={ // width= 20 height= 20 imgtype=rgb565
0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,
0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0x00,0xf8,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xf8,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,
0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xff,0xff,
0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,
}

文本转图像

对图像数据写入时,要注意一点,那就是QImage的行有自动对齐功能,比如说你现在创建一个20x20大小的灰度图像,那图像每行的byte数就是20,也就是imgdst->bytesPerLine() 和你的imgdst->width() 是相等的,但如果你创建的是31x31的,你的imgdst->bytesPerLine() 就是32,而width() 仍旧是31。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值