<2>[QTCN]图片数据转换工具

参考

<2>[QTCN]图片数据转换工具

  • 说明:图片数据转换工具,可以批量将图片转换成数据,将数据转换为图片。
  • 亮点:延时处理,图片数据解码,16进制格式和base64格式,进度条同步显示,文件保存等。
  • 新增: 自动推算路径无需再选择(不存在则自动创建)

实现

main.cpp

#include "imagetodatatools.h"

#include <QApplication>
#include <QFont>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // 设置全局字体大小
    QFont font;
    font.setPointSize(15);  // 设置字体大小
    qApp->setFont(font);
    ImageToDataTools w;
    w.show();
    return a.exec();
}

imagetodatatools.h

#ifndef IMAGETODATATOOLS_H
#define IMAGETODATATOOLS_H
#pragma execution_character_set("utf-8")

#include <QWidget>
#include <QDesktopWidget>
#include <QTimer>
#include <QDateTime>
#include <QFileDialog>
#include <QDebug>
#include <QMessageBox>
#include <QListWidgetItem>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QBuffer>
#include <QImage>

QT_BEGIN_NAMESPACE
namespace Ui { class ImageToDataTools; }
QT_END_NAMESPACE

class ImageToDataTools : public QWidget

{
    Q_OBJECT

public:
    ImageToDataTools(QWidget *parent = nullptr);
    ~ImageToDataTools();

private:
    Ui::ImageToDataTools *ui;

public:
    void initUI();
    void ShowTime();
    void DelayTime(int s);
    void PicToData(QString fromPic,QString toData,QString myformat);//图片转数据
    void DataToPic(QString fromData,QString toPic,QString myformat);//数据转图片

private slots:
    void on_btnBrowseToPic_clicked();
    void on_btnBrowseToTxt_clicked();
    void on_btnPicToData_clicked();
    void on_btnDataToPic_clicked();
    void on_btnSelectFile_clicked();
    void on_btnSelectTxt_clicked();
    void on_btnChangeToJpg_clicked();
    void on_btnChangeToTxt_clicked();
    void on_listWidget_doubleClicked(const QModelIndex &index);
protected:
    void dragEnterEvent(QDragEnterEvent *event) override;   // 处理拖动操作进入窗口事件
    void dropEvent(QDropEvent *event) override;             //处理拖放操作完成的事件。当拖动的数据在窗口上释放时,会触发该事件
};

#endif // IMAGETODATATOOLS_H

imagetodatatools.cpp

#include "imagetodatatools.h"
#include "ui_imagetodatatools.h"

ImageToDataTools::ImageToDataTools(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ImageToDataTools)
{
    ui->setupUi(this);
    initUI();
}

ImageToDataTools::~ImageToDataTools()
{
    delete ui;
}

void ImageToDataTools::initUI()
{
    //窗体居中显示
    QDesktopWidget *desktop=QApplication::desktop();
    int width=desktop->width();
    int height=desktop->height();
    //设置窗口将始终显示在其他窗口之上
    setWindowFlags(Qt::WindowStaysOnTopHint);
    this->move((width-this->width())/2,(height-this->height())/2);

    setWindowIcon(QIcon(":/1.ico"));
    setWindowTitle(tr("图片数据转换工具"));
    this->setAcceptDrops(true);                    //设置允许向窗口拖入

    // 定时器更新
    QTimer *updateTimer = new QTimer(this);
    updateTimer->callOnTimeout(this,&ImageToDataTools::ShowTime);
    updateTimer->start(1000);
}

void ImageToDataTools::ShowTime()
{
    QDateTime time=QDateTime::currentDateTime();
    QString s=time.toString("yyyy年MM月dd日 hh时mm分ss秒 dddd");
    ui->labTime->setText(tr("现在是:%1").arg(s));
}

void ImageToDataTools::DelayTime(int s)
{
    QTime t=QTime::currentTime().addMSecs(s);       // addMSecs(s) 将当前时间增加指定的毫秒数s,得到一个目标时间点t
    while(QTime::currentTime()<t){                  /*处理当前线程的事件队列,并等待最多100毫秒来接收新的事件。
                                                    这是为了确保程序的其他部分仍然能够响应用户操作,避免程序卡死。*/
        QCoreApplication::processEvents(QEventLoop::AllEvents,100);
    }
}

//图片转数据
void ImageToDataTools::PicToData(QString fromPic, QString toData, QString myformat)
{
    QImage img(fromPic);
    // 保存图像数据到 QByteArray
    QByteArray ba;
    QBuffer buf(&ba);
    buf.open(QIODevice::WriteOnly);
    img.save(&buf,"JPG");                           //按照JPG解码保存数据
    buf.close();

    QByteArray cc=qCompress(ba,1);                  // 对图像数据进行压缩

    QByteArray hh;
    if (myformat=="Hex")
    {
        hh=cc.toHex();                              //获取十六进制数据
    }
    else
    {
        hh=cc.toBase64();                           //获取Base64数据
    }
    /*
     * 将hh直接写入文件可能会导致文件保存的是二进制数据,而不是文本数据。
     * 由于文件通常存储文本数据,而不是二进制数据,将QByteArray以文本格式写入文件是常见的做法
     */
    QString str(hh);

    QFile file(toData);
    if (file.open(QFile::WriteOnly|QFile::Truncate))
    {
        file.write(str.toLatin1());                 // 字符编码是Latin1可以表示大多数ASCII字符
        file.close();
    }
}

//数据转图片
void ImageToDataTools::DataToPic(QString fromData, QString toPic, QString myformat)
{
    QFile file(fromData);
    if (file.open(QFile::ReadOnly))
    {
        QByteArray read = file.readAll();
        file.close();

        QByteArray rc;
        if (myformat == "Hex")
        {
            //QString hexString = QString::fromLatin1(read);          // Latin1编码方式写入文件,读取转换为字符串
            //rc = QByteArray::fromHex(hexString.toLatin1());         // 解析十六进制字符串
            rc = QByteArray::fromHex(read);
        }
        else
        {
            rc = QByteArray::fromBase64(read);
        }
        QByteArray rdc = qUncompress(rc);                           // 解压缩,得到解压后的二进制数据

        QImage img;
        img.loadFromData(rdc);
        img.save(toPic);
    }
}



void ImageToDataTools::on_btnBrowseToPic_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("选择图片文件"), "", tr("图片文件(*.jpg;*.gif;*.bmp;*.png;*.jpeg)"));
    if (fileName.isEmpty())                         // 用户取消选择或者没有选择有效的文件
        fileName= "未选择图片";

    ui->pic->setText(fileName);
    // 自动推算txt路径
    QFileInfo fileInfo(fileName);
    QString txtPath(fileName.remove(fileInfo.suffix())+"txt");// 文件的后缀名
    ui->txt->setText(txtPath);
}


void ImageToDataTools::on_btnBrowseToTxt_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("选择文本文件"), "", tr("文本文件(*.txt)"));
    if (fileName.isEmpty())                         // 用户取消选择或者没有选择有效的文件
        fileName= "未选择文本";

    ui->txt->setText(fileName);
    // 自动推算pic路径
    QFileInfo fileInfo(fileName);
    QString picPath(fileName.remove(fileInfo.suffix())+"jpg");// 文件的后缀名
    ui->pic->setText(picPath);

}

// 图片转数据
void ImageToDataTools::on_btnPicToData_clicked()
{
    if (ui->pic->text()==""||ui->pic->text()=="未选择图片")
    {
        QMessageBox::information(this,tr("提示"),tr("请选择图片文件"));
        return;
    }
    if (ui->txt->text()==""||ui->txt->text()=="未选择文本")
    {
        QMessageBox::information(this,tr("提示"),tr("请选择文本文件"));
        return;
    }
    if (ui->rbtn16->isChecked())
    {
        PicToData(ui->pic->text(),ui->txt->text(),"Hex");
    }
    else
    {
        PicToData(ui->pic->text(),ui->txt->text(),"Base64");
    }
    QMessageBox::information(this,tr("提示"),tr("恭喜你!转换完成!"));
}

// 数据转图片
void ImageToDataTools::on_btnDataToPic_clicked()
{
    if (ui->pic->text()==""||ui->pic->text()=="未选择图片")
    {
        QMessageBox::information(this,tr("提示"),tr("请选择图片文件"));
        return;
    }
    if (ui->txt->text()==""||ui->txt->text()=="未选择文本")
    {
        QMessageBox::information(this,tr("提示"),tr("请选择文本文件"));
        return;
    }
    if (ui->rbtn16->isChecked())
    {
        DataToPic(ui->txt->text(),ui->pic->text(),"Hex");
    }
    else
    {
        DataToPic(ui->txt->text(),ui->pic->text(),"Base64");
    }
    QMessageBox::information(this,tr("提示"),tr("恭喜你!转换完成!"));
}

// 选择JPG
void ImageToDataTools::on_btnSelectFile_clicked()
{
    QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("选择图片文件"), "", tr("图片文件(*.jpg;*.gif;*.bmp;*.png;*.jpeg)"));
    if (!fileNames.isEmpty())                       // 用户选择有效的文件
        ui->listWidget->addItems(fileNames);
    else
        qDebug() << "未选择文件";
}

// 选择TXT
void ImageToDataTools::on_btnSelectTxt_clicked()
{
    QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("选择文本文件"), "", tr("文本文件(*.txt)"));
    if (!fileNames.isEmpty())// 用户选择有效的文件
        ui->listWidget->addItems(fileNames);
    else
        qDebug() << "未选择文件";
}

// 批量转图片
void ImageToDataTools::on_btnChangeToJpg_clicked()
{
    QListWidgetItem *myitem;
    int count=ui->listWidget->count();
    if (count==0)
    {
        QMessageBox::information(this,tr("提示"),tr("请选择图片文件"));
        return;
    }

    ui->pbar->setValue(0);
    ui->pbar->setMaximum(count);

    for (int i=0;i<count;i++)
    {
        QString timeNow=QDateTime::currentDateTime().toString("yyyyMMddHHmmss");
        QString saveFileName=QCoreApplication::applicationDirPath()+QString("/%1.jpg").arg(timeNow);
        myitem=ui->listWidget->item(i);
        if (ui->rbtn16->isChecked())
        {
            DataToPic(myitem->text(),saveFileName,"Hex");
        }
        else
        {
            DataToPic(myitem->text(),saveFileName,"Base64");
        }
        ui->pbar->setValue(ui->pbar->value()+1);
        this->DelayTime(1000);                      //为了确保命名不冲突和转换完成,延时1秒
    }
    QMessageBox::information(this,tr("提示"),tr("恭喜你!转换完成!"));
}

// 批量转TXT
void ImageToDataTools::on_btnChangeToTxt_clicked()
{
    QListWidgetItem *myitem;
    int count=ui->listWidget->count();
    if (count==0)
    {
        QMessageBox::information(this,tr("提示"),tr("请选择文本文件"));
        return;
    }

    ui->pbar->setValue(0);
    ui->pbar->setMaximum(count);

    for (int i=0;i<count;i++)
    {
        QString timeNow=QDateTime::currentDateTime().toString("yyyyMMddHHmmss");
        QString saveFileName=QCoreApplication::applicationDirPath()+QString("/%1.txt").arg(timeNow);
        qDebug()<<"saveFileName ="<<saveFileName;
        myitem=ui->listWidget->item(i);
        if (ui->rbtn16->isChecked())
        {
            PicToData(myitem->text(),saveFileName,"Hex");
        }
        else
        {
            PicToData(myitem->text(),saveFileName,"Base64");
        }
        ui->pbar->setValue(ui->pbar->value()+1);
        this->DelayTime(1000);                      //为了确保命名不冲突和转换完成,延时1秒
    }
    QMessageBox::information(this,tr("提示"),tr("恭喜你!转换完成!"));
}

// 双击项
void ImageToDataTools::on_listWidget_doubleClicked(const QModelIndex &index)
{
    // 示例:获取双击的项的文本
    QString text = ui->listWidget->item(index.row())->text();
    qDebug() << "双击了:" << text;
                ui->listWidget->clear();
}

// 处理拖动操作进入窗口事件
void ImageToDataTools::dragEnterEvent(QDragEnterEvent *event)
{ // 处理拖动操作进入的逻辑
    if (event->mimeData()->hasUrls())                  //检查拖放事件的数据是否包含 URL
    {
        QList<QUrl> urls = event->mimeData()->urls();
        foreach (const QUrl &url, urls)
        {
            QString fileName = url.toLocalFile();      // 获取文件的本地路径
            QFileInfo fileInfo(fileName);
            // 将文件的后缀名转换为小写
            if (fileInfo.suffix().toLower() == "jpg" ||
                fileInfo.suffix().toLower() == "gif" ||
                fileInfo.suffix().toLower() == "bmp" ||
                fileInfo.suffix().toLower() == "png" ||
                fileInfo.suffix().toLower() == "jpeg")
            {
                event->acceptProposedAction();          // 接受拖放操作
                return;
            }
        }
    }
    event->ignore();                                    //没有找到匹配的图片文件,忽略拖放操作
}

//处理拖放操作完成的事件。当拖动的数据在窗口上释放时,会触发该事件
void ImageToDataTools::dropEvent(QDropEvent *event)
{
    // 处理文件或文件路径的拖放
    QList<QUrl> urls = event->mimeData()->urls();
    foreach (const QUrl& url, urls) {
        QString filePath = url.toLocalFile();
        qDebug() << "拖放文件:" << filePath;
    }
    if (urls.isEmpty())
        return;

    QString filePath=urls.first().toLocalFile();
    ui->pic->setText(filePath);
}

imagetodatatools.ui

在这里插入图片描述

效果

在这里插入图片描述

源码

Gitee:02ImageToDataTools[QTCN]图片数据转换工具

模糊知识点

  1. 处理当前线程的事件队列,并等待100毫秒来接收新的事件。
// addMSecs(s) 将当前时间增加指定的毫秒数s,得到一个目标时间点t
QTime t=QTime::currentTime().addMSecs(s);       
while(QTime::currentTime()<t){                 
	QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}

为了确保程序的其他部分仍然能够响应用户操作,避免程序卡死。

  1. 文件 通常存储 文本数据,而不是 二进制数据,将QByteArray以文本格式Latin1字符编码 写入文件是常见的做法
//图片转数据
void ImageToDataTools::PicToData(QString fromPic, QString toData, QString myformat)
{
    QImage img(fromPic);
    // 保存图像数据到 QByteArray
    QByteArray ba;
    QBuffer buf(&ba);
    buf.open(QIODevice::WriteOnly);
    img.save(&buf,"JPG");                           //按照JPG解码保存数据
    buf.close();

    QByteArray cc=qCompress(ba,1);                  // 对图像数据进行压缩

    QByteArray hh;
    if (myformat=="Hex")
    {
        hh=cc.toHex();                              //获取十六进制数据
    }
    else
    {
        hh=cc.toBase64();                           //获取Base64数据
    }
    /*
     * 将hh直接写入文件可能会导致文件保存的是二进制数据,而不是文本数据。
     * 由于文件通常存储文本数据,而不是二进制数据,将QByteArray以文本格式写入文件是常见的做法
     */
    QString str(hh);

    QFile file(toData);
    if (file.open(QFile::WriteOnly|QFile::Truncate))
    {
        file.write(str.toLatin1());                 // 字符编码是Latin1可以表示大多数ASCII字符
        file.close();
    }
}
  1. **QFile::Truncate**只能创建QCoreApplication::applicationDirPath()路径下的文件,不能创建再带有路径的,如QCoreApplication::applicationDirPath()/imagexx/xxx.txt,如果路径中的imagexx文件夹不存在,使用 QFile 直接创建文件时将无法成功创建文件 /imagexx/xxx.txt

可以通过

QString filePath = QCoreApplication::applicationDirPath() + "/imagexx/xxx.txt";

QDir folder(QCoreApplication::applicationDirPath());
if (!folder.exists("imagexx")) // 检查文件夹是否存在
{
    if (!folder.mkpath("imagexx")) // 创建文件夹并检查是否成功
    {
        // 创建文件夹失败,进行适当的错误处理
        return;
    }
}

QFile file(filePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
    // 进行文件写入操作...
    file.close();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值