【QT小玩具】将图片转换为字符

1、首先是界面

widget.h

#include <QWidget>
#include <QImage>
#include <QFileDialog>
#include <QPushButton>
#include <QLabel>
#include <QPainter>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QVBoxLayout>

class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = 0);
    ~Widget();
protected:
    QPushButton *getImageBtn;
    QPushButton *transformBtn;
    QLineEdit *inputRatioEdit;
    QLineEdit *outputRatioEdit;

    QLabel *showImageLabel;
    QLabel *printLabel;

    QVBoxLayout *optionLayout;
    QHBoxLayout *mainLayout;
};

 widget.cpp 

 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    getImageBtn = new QPushButton("打开图片",this);
    transformBtn = new QPushButton("开始转换",this);
    inputRatioEdit = new QLineEdit("1-输入比例",this);
    outputRatioEdit = new QLineEdit("1-输出比例",this);

    showImageLabel = new QLabel(this);
    printLabel = new QLabel(this);

    optionLayout = new QVBoxLayout;
    optionLayout->addWidget(getImageBtn,0);
    optionLayout->addWidget(transformBtn,1);
    optionLayout->addWidget(inputRatioEdit,2);
    optionLayout->addWidget(outputRatioEdit,3);

    mainLayout = new QHBoxLayout(this);
    mainLayout->addWidget(showImageLabel,0);
    mainLayout->addLayout(optionLayout,1);
    mainLayout->addWidget(printLabel,2);
}

 ok到此为止我们需要的界面就完成了,虽然很简陋就是了 

2、连接槽

在类内添加如下代码

 
    QString m_image;
    double inputScalingRatio;
    double outputScalingRatio;

public slots:
    void readFile();
    void transformation();
    void inputScalingRatioChange(QString str);
    void outputScalingRatioChange(QString str);

 在构造函数内连接槽 

    connect(transformBtn,SIGNAL(clicked()),this,SLOT(transformation()));
    connect(inputRatioEdit,SIGNAL(textEdited(QString)),this,SLOT(inputScalingRatioChange(QString)));
    connect(outputRatioEdit,SIGNAL(textEdited(QString)),this,SLOT(outputScalingRatioChange(QString)));

 槽函数的实现 

readFile()

{
    QString s=QFileDialog::getOpenFileName(this,"open Image","/",
                                           "Images (*.png *.jpg)");
    if(s.isEmpty())
        return;
    m_image = s;
    QPixmap pixmap(s);
    pixmap = pixmap.scaled(pixmap.width()*inputScalingRatio,pixmap.height()*inputScalingRatio,Qt::KeepAspectRatio);
    showImageLabel->setPixmap(pixmap);
}

 读取文件并保存文件信息,之后把图片进行缩放后显示到showImageLabel里  

inputScalingRadioChange()

{
    if(str.toDouble()<0||str.toDouble()>10)
    {
        inputRatioEdit->setText(QString::number(inputScalingRatio));
        return;
    }

    inputScalingRatio = str.toDouble();

    if(showImageLabel->pixmap() == 0)
        return;

    QPixmap pixmap(m_image);
    pixmap = pixmap.scaled(pixmap.width()*inputScalingRatio,pixmap.height()*inputScalingRatio,Qt::KeepAspectRatio);
    showImageLabel->setPixmap(pixmap);
}

 改变输入的缩放比,在确认输入有意义后将重新设置显示 

outputScalingRatioChange()

void Widget::outputScalingRatioChange(QString str)
{
    if(str.toDouble()<0||str.toDouble()>10)
    {
        outputRatioEdit->setText(QString::number(inputScalingRatio));
        return;
    }

    outputScalingRatio = str.toDouble();

    if(printLabel->pixmap() == 0)
            return;

    transformation();
}

同上,改变输出比例

剩下一个槽单独进行讲解


3、transformation()

这个槽也就是最关键的转换了,在贴代码之前先解释一下其原理

转换分为4个步骤

1.获取图片

2.缩放

3.将像素值灰度化后存入数组

4.根据灰度值转换为字符并显示


先在头文件里定义

#define W_G 0.59
#define W_B 0.3

#define CW 5
#define CH 10

const QString print_char(".,`^*~:;!\\+(){}[]&$%#@");

 这三项分别是灰度化转换时的权重,显示时字符间距和所要显示的字符 

transformation()

void Widget::transformation()
{
    QImage image = showImageLabel->pixmap()->toImage();

    image = image.scaled(image.width()/CW*outputScalingRatio,image.height()/CH*outputScalingRatio);

    int **RGBArray = toRGBArray(image);
    if(RGBArray == 0)
        return;

    printText(RGBArray,image.width(),image.height());

    for(int i = 0;i < image.width();i++)
        delete[] RGBArray[i];
    delete[] RGBArray;
}

直接从showImageLabel里获取图片,将其根据缩放比和字符距离进行缩放,

然后通过toRGBArray()进行转换,再通过printText进行输出,

最后释放创建的数组


在类内添加

private:
    int** toRGBArray(QImage image);
    void printText(int** RGBArray,int W,int H);

用于实现第三步和第四步


toRGBArray()

int** Widget::toRGBArray(QImage image)
{
    if(image.isNull())
        return 0;

    int W = image.width();
    int H = image.height();

    int **RGBArray = new int*[W];
    for(int i = 0;i < W;i++)
    {
        RGBArray[i] = new int[H];
    }

    for(int x = 0;x < W;x++)
        for(int y = 0;y < H;y++)
        {
            QColor rgb = image.pixel(x,y);
            RGBArray[x][y] = rgb.red()*W_R + rgb.green()*W_G + rgb.blue()*W_B;
        }

    return RGBArray;
}

将对应像素的rgb值根据权重转换为灰度值后存入数组

printText()

void Widget::printText(int** RGBArray, int W, int H)
{
    QPixmap pixmap(CW*W,CH*H);
    pixmap.fill(QColor(0,0,0));

    QPainter painter(&pixmap);
    painter.setPen(QColor(255,255,255));

    for(int y = 0;y < H;y++)
    {
        for(int x = 0;x < W;x++)
        {
            painter.drawText(CW*x,CH*y,CW,CH,Qt::AlignCenter,print_char[RGBArray[x][y]/12]);
        }
    }

    printLabel->setPixmap(pixmap);
}

为了显示的更美观,决定将字符画在图片上进行输出(如需文本文件可自行在循环内添加文本输出代码)


最终效果













  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
众所周知,人工智能是当前最热门的话题之一, 计算机技术与互联网技术的快速发展更是将对人工智能的研究推向一个新的高潮。 人工智能是研究模拟和扩展人类智能的理论与方法及其应用的一门新兴技术科学。 作为人工智能核心研究领域之一的机器学习, 其研究动机是为了使计算机系统具有人的学习能力以实现人工智能。 那么, 什么是机器学习呢? 机器学习 (Machine Learning) 是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析的一门学科。 机器学习的用途 机器学习是一种通用的数据处理技术,其包含了大量的学习算法。不同的学习算法在不同的行业及应用中能够表现出不同的性能和优势。目前,机器学习已成功地应用于下列领域: 互联网领域----语音识别、搜索引擎、语言翻译、垃圾邮件过滤、自然语言处理等 生物领域----基因序列分析、DNA 序列预测、蛋白质结构预测等 自动化领域----人脸识别、无人驾驶技术、图像处理、信号处理等 金融领域----证券市场分析、信用卡欺诈检测等 医学领域----疾病鉴别/诊断、流行病爆发预测等 刑侦领域----潜在犯罪识别与预测、模拟人工智能侦探等 新闻领域----新闻推荐系统等 游戏领域----游戏战略规划等 从上述所列举的应用可知,机器学习正在成为各行各业都会经常使用到的分析工具,尤其是在各领域数据量爆炸的今天,各行业都希望通过数据处理与分析手段,得到数据中有价值的信息,以便明确客户的需求和指引企业的发展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值