<2>Herramienta de conversión de datos de imagen [QTCN]

referencia

<2>Herramienta de conversión de datos de imágenes [QTCN]

  • Descripción: una herramienta de conversión de datos de imágenes que puede convertir imágenes en datos y datos en imágenes por lotes.
  • Aspectos destacados: procesamiento de retraso, decodificación de datos de imagen, formatos hexadecimales y base64, visualización sincrónica de la barra de progreso, guardado de archivos, etc.
  • Nuevo: no es necesario seleccionar la ruta para el cálculo automático (se creará automáticamente si no existe)

lograr

principal.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

inserte la descripción de la imagen aquí

Efecto

inserte la descripción de la imagen aquí

código fuente

Gitee: 02ImageToDataTools[QTCN] herramienta de conversión de datos de imagen

puntos de conocimiento borrosos

  1. Procesa la cola de eventos del subproceso actual y espera 100 milisegundos para recibir nuevos eventos.
// addMSecs(s) 将当前时间增加指定的毫秒数s,得到一个目标时间点t
QTime t=QTime::currentTime().addMSecs(s);       
while(QTime::currentTime()<t){
    
                     
	QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}

Para garantizar que otras partes del programa aún puedan responder a las operaciones del usuario, para evitar que el programa se atasque.

  1. 文件Por lo general, almacenar 文本数据, en lugar de 二进制数据escribir, un QByteArray en un archivo en formato de texto. La codificación de caracteres Latin1 es una práctica común.
//图片转数据
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** Solo se pueden crear archivos en la ruta de QCoreApplication::applicationDirPath() y no se pueden crear archivos con rutas, como QCoreApplication::applicationDirPath()/imagexx/xxx.txt. Si la carpeta imagexx en la ruta no existe, al usar QFile para crear un archivo directamente, el archivo /imagexx/xxx.txt no se creará correctamente

capaz de pasar

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();
}

Supongo que te gusta

Origin blog.csdn.net/qq_47355554/article/details/131671323
Recomendado
Clasificación