Create an identity image from a string

If you want to generate an image to identify multiple objects, here is the right place you come.
This is the identity image without overly.
Without overlay
This is the identity image with overlay.
With overlay
In a project, I want to generate an image to identify my multiple USB devices in C++ with Qt. Thanks to Qt in which there are a lot of pre-created classes for us to use, for example, QImage, QPixmap, QPainter, QString, QCryptographicHash, etc. which can be used in my project, I can fulfill my task easily.

Rationale

First of all, let me simply explain the rationale of the creation.

  1. Generate a hash number from the specified string. MD5 is a good choice to do so. Certainly, other methods can also be used, such as SM3, MD4, Sha224, Sha256, Sha384, Sha512, etc. Even you can create a hash function by yourself. I was using MD5, because MD5 is the best function we can get easily.
  2. Dissolve the generated hash number and reorganize the data we are going to use. 4 bits are used for color, 4 bits for size, 4 bits for x, 4 bits for y. To implement the dissolving the data, structure and union can be used. For detail, see the source code below.
  3. To calculate the background color, add all bytes of the hash number. Only the least 4 bits of the sum are use to choose the background color. The 16 background colors can be customized in file IDImage.h.
  4. Draw a solid square with the size and color at the point of (x, y) for each word (2 bytes) of the hash umber. Maybe you want to get some information beneath the square. If so, the solid square must be transparent, you can specify the alpha channel with setAlpha() function. Normally, 128 might be a propriate value.
  5. Repeat step 4 until all the data are processed.

IDImage.h

#pragma once
#include <qimage.h>
#include <qpixmap.h>
#include <qpainter.h>
#include <qstring.h>
#include <qcryptographichash.h>

#pragma pack(1)
typedef union U {
	struct {
		unsigned char b0;
		unsigned char b1;
	} b;
	struct {
		unsigned char color : 4;
		unsigned char size : 4;
		unsigned char x : 4;
		unsigned char y : 4;
	} p;
} UMark;
#pragma pack()

class IDImage : QObject
{
	Q_OBJECT
public:
	IDImage(int w = 64, int h = 64);
	~IDImage();

	QPixmap* createImage(QString s);
	QPixmap* getImage();
	bool saveImage(QString path = NULL);

private:
	QColor getBackgroundColor(QByteArray b);

	QPixmap* m_image;
	int m_w, m_h;

	QVector<QColor> g_bcolor{
		QColor::fromRgb(0, 0, 139),//darkblue	rgb(0, 0, 139)
		QColor::fromRgb(0, 139, 139),//darkcyan	rgb(0, 139, 139)
		QColor::fromRgb(184, 134, 11),//darkgoldenrod	rgb(184, 134, 11)
		QColor::fromRgb(0, 100, 0),//darkgreen	rgb(0, 100, 0)
		QColor::fromRgb(189, 183, 107),//darkkhaki	rgb(189, 183, 107)
		QColor::fromRgb(139, 0, 139),//darkmagenta	rgb(139, 0, 139)
		QColor::fromRgb(85, 107, 47),//darkolivegreen	rgb(85, 107, 47)
		QColor::fromRgb(255, 140, 0),//darkorange	rgb(255, 140, 0)
		QColor::fromRgb(153, 50, 204),//darkorchid	rgb(153, 50, 204)
		QColor::fromRgb(139, 0, 0),//darkred	rgb(139, 0, 0)
		QColor::fromRgb(233, 150, 122),//darksalmon	rgb(233, 150, 122)
		QColor::fromRgb(143, 188, 143),//darkseagreen	rgb(143, 188, 143)
		QColor::fromRgb(72, 61, 139),//darkslateblue	rgb(72, 61, 139)
		QColor::fromRgb(0, 206, 209),//darkturquoise	rgb(0, 206, 209)
		QColor::fromRgb(148, 0, 211),//darkviolet	rgb(148, 0, 211)
		QColor::fromRgb(34, 139, 34)//forestgreen	rgb(34, 139, 34)
	};

	QVector<QColor> g_fcolor{
		QColor::fromRgb(255, 192, 203),//pink	rgb(255, 192, 203)
		QColor::fromRgb(221, 160, 221),//plum	rgb(221, 160, 221)
		QColor::fromRgb(176, 224, 230),//powderblue	rgb(176, 224, 230)
		QColor::fromRgb(128, 0, 128),//purple	rgb(128, 0, 128)
		QColor::fromRgb(255, 0, 51),//
		QColor::fromRgb(188, 143, 143),//rosybrown	rgb(188, 143, 143)
		QColor::fromRgb(65, 105, 225),//royalblue	rgb(65, 105, 225)
		QColor::fromRgb(139, 69, 19),//saddlebrown	rgb(139, 69, 19)
		QColor::fromRgb(250, 128, 114),//salmon	rgb(250, 128, 114)
		QColor::fromRgb(244, 164, 96),//sandybrown	rgb(244, 164, 96)
		QColor::fromRgb(46, 139, 87),//seagreen	rgb(46, 139, 87)
		QColor::fromRgb(255, 245, 238),//seashell	rgb(255, 245, 238)
		QColor::fromRgb(160, 82, 45),//sienna	rgb(160, 82, 45)
		QColor::fromRgb(153, 153, 51),//
		QColor::fromRgb(135, 206, 235),//skyblue	rgb(135, 206, 235)
		QColor::fromRgb(106, 90, 205) //slateblue	rgb(106, 90, 205) 
	};

};

IDImage.cpp

#include "stdafx.h"
#include "IDImage.h"

IDImage::IDImage(int w /*= 64*/, int h /*= 64*/)
{
	m_image = new QPixmap(w, h);
	m_w = w;
	m_h = h;
}

IDImage::~IDImage()
{
	if (m_image != nullptr) {
		delete m_image;
	}
}

QPixmap* IDImage::createImage(QString s)
{
	QByteArray hash = QCryptographicHash::hash(s.toUtf8(), QCryptographicHash::Md5);
	if (m_image != nullptr) {
		QPainter paint(m_image);
		paint.fillRect(0, 0, m_w, m_h, getBackgroundColor(hash));
		for (int i = 0; i < hash.size(); i += 2) {
			UMark data;
			data.b.b0 = hash.at(i);
			data.b.b1 = hash.at(i + 1);
			QColor color = g_fcolor.at(data.p.color);
			color.setAlpha(128);
			int max_size = (m_w < m_h) ? m_w : m_h;
			int size = (data.p.size + 1) * max_size / 33;
			int x = data.p.x * m_w / 16 - size;
			int y = data.p.y * m_h / 16 - size;
			paint.fillRect(x, y, 2 * size, 2 * size, color);
		}
		//If you want to overlay the image with some interesting image,
		//please specify the overly and uncomment the lines below.
		//QImage hard_key(":/MainFrame/Resources/common/hard_key.png");
		//hard_key.scaled(QSize(m_w, m_h));
		//paint.drawImage(QPoint(0, 0), hard_key);
	}
	return m_image;
}

QPixmap * IDImage::getImage()
{
	return m_image;
}

bool IDImage::saveImage(QString path)
{
	return m_image->save(path, "PNG");
}

QColor IDImage::getBackgroundColor(QByteArray b)
{
	int t = 0;
	for (int i = 0; i < b.size(); i += 1) {
		t += b.at(i);
	}
	t &= 0xf;
	return g_bcolor.at(t);
}

How to use the class IDImage

#include "IDImage.h"
...
IDImage img(64, 64);
img.createImage(_here_is_the_identity_string_);
if (!img.saveImage(_path_to_the_image_)
{
	//handle the error
}

Fine tune your own code

  • The background colors can be customized in IDImage.h. In my opinion, the darker the better.
  • The foreground colors can also be customized in IDImage.h. Again, in my opinion, the brighter the better.
  • The principle to choose the background colors and foreground colors is that the bigger the distinguishability the better. Also, you may take the color series into consideration. Anyway, all depends on how you design.
  • If you want to put something on top of the generated image, uncomment the lines in the source code, and make sure to provide the image with the application.
  • In the source code, the input is a string. In fact, the input can be any data type, because the real data we used is the MD5 of the original input. So, you can create the overloaded functions by yourself.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CREATE TABLE `advert` ( `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(100) COLLATE utf8mb4_bin NOT NULL COMMENT '广告名称', `position_id` int(20) NOT NULL COMMENT '广告位置ID', `media_id` int(20) NOT NULL COMMENT '广告图片ID', `link` varchar(500) COLLATE utf8mb4_bin NOT NULL COMMENT '广告链接', `status` int(1) unsigned zerofill NOT NULL COMMENT '状态,0:未启用,1:已启用,2:已结束', PRIMARY KEY (`id`) USING BTREE, KEY `FK_ad_image` (`media_id`), KEY `FK_ad_position` (`position_id`), CONSTRAINT `FK_ad_image` FOREIGN KEY (`media_id`) REFERENCES `media_file` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `FK_ad_position` FOREIGN KEY (`position_id`) REFERENCES `ad_position` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='广告表'; CREATE TABLE `ad_position` ( `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT '位置名称', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='广告位置表'; CREATE TABLE `media_file` ( `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(30) COLLATE utf8mb4_bin NOT NULL COMMENT '媒体文件名称', `type` tinyint(1) NOT NULL COMMENT '媒体文件类型:0-图片,1-视频', `url` varchar(500) COLLATE utf8mb4_bin NOT NULL COMMENT '媒体文件URL地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='广告媒体文件表'; springboot项目用java写出三张表的orm对象(使用jpa外键依赖)
06-02

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值