使用qt強大的圖形處理功能
將兩幅圖融合後保存,可交叉編譯供外部應用使用
#include <QImage>
#include <QMatrix>
#include <QDebug>
#include <string.h>
#include <QPainter>
#include <QDesktopWidget>
#include <QPaintDevice>
#include <time.h>
#include <QFileInfo>
#include <sys/time.h>
#include <QImageReader>
#define REC_MAX_PIC_WIDTH (float)756 //756 pix
#define REC_MAX_PAPER_WIDHT (float)20 //(20cm)
//debug show window or not
#define DEBUG_SHOW
#define USE_IMG_METHOD
//enable up down line
#define UP_DOWN_LINE_ENABLE
#define LEFT_RIGHT_LINE_ENABLE
#ifdef DEBUG_SHOW
#include <QApplication>
#include <QLabel>
#define INPUT_FILE_NAME "in.jpg"
#define OUTPUT_FILE_NAME "out.jpg"
#define COUPLET_WIDTH (float)22
//#define UP_DOWN_INTERVAL 0.03 //(float)COUPLET_WIDTH/20
#define UP_DOWN_INTERVAL 2.2 //(float)COUPLET_WIDTH/20
#define ROTATION_DEGREE 45
#endif
int line_enable = 0;
long timestamp(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec*1000 + tv.tv_usec/1000);
}
QImage createImageWithOverlay(const QImage& baseImage, const QImage& overlayImage, int start_x, int start_y)
{
int i;
QImage imageWithOverlay = QImage(baseImage.size(), QImage::Format_ARGB32_Premultiplied);
QPainter painter(&imageWithOverlay);
QPen pen;
int inteval = 10;
pen.setWidth(1);
painter.setPen(pen);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(imageWithOverlay.rect(), Qt::transparent);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.drawImage(0, 0, baseImage);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.drawImage(start_x, start_y, overlayImage);
if(line_enable != 0) {
#ifdef UP_DOWN_LINE_ENABLE
for(i = 0; i < overlayImage.width(); i += inteval*2)
{
painter.drawLine(i + start_x, 0, i + start_x + inteval, 0);
}
for(i = 0; i < overlayImage.width(); i += inteval*2)
{
painter.drawLine(i + start_x, baseImage.height() - 1, i + start_x + inteval, baseImage.height() - 1);
}
#endif
#ifdef LEFT_RIGHT_LINE_ENABLE
for(i = 0; i < baseImage.height(); i += inteval*2)
{
painter.drawLine(0, i, 0, i + inteval);
}
for(i = 0; i < baseImage.height(); i += inteval*2)
{
painter.drawLine(baseImage.width() - 1, i, baseImage.width() - 1, i + inteval);
}
#endif
}
painter.end();
return imageWithOverlay;
}
int main( int argc, char **argv)
{
long start = timestamp();
float image_h;
float image_w;
float set_front_width;
float set_front_height;
float set_background_width;
float set_background_height;
float rate;
float set_size;
float up_down_edge = 0;
char input_name[200] = {0};
char output_name[200] = {0};
char cmd[256] = {0};
int ro_degree = 0;
int extra_size = 0;
int dot_per_meter_x = 0;
int dot_per_meter_y = 0;
QMatrix matrix;
#ifdef DEBUG_SHOW
QApplication a(argc, argv);
QLabel label;
set_size = COUPLET_WIDTH;
up_down_edge = UP_DOWN_INTERVAL;
ro_degree = ROTATION_DEGREE;
line_enable = 1;
sprintf(input_name, "%s", INPUT_FILE_NAME);
sprintf(output_name, "%s", OUTPUT_FILE_NAME);
#else
if(argc == 2) {
qDebug() << QImageReader::supportedImageFormats();
}
if(argc != 6 && argc != 7) {
printf("input error,input num error:%d, use [couplet [1~24] interval[1~24] rotation[0~360] in_file outfile]\n", argc);
return 0;
}
if(argc == 7) {
line_enable = 1;
} else {
line_enable = 0;
}
set_size = atof(argv[1]);
if(set_size < 0 || set_size > 24) {
printf("input error,size error %f, use [couplet [1~24] interval[1~24] rotation[0~360] in_file outfile]\n", set_size);
return 0;
}
up_down_edge = atof(argv[2]);
if(up_down_edge < 0 || up_down_edge > 24) {
printf("input error,interval error %f, use [couplet [1~24] interval[1~24] rotation[0~360] in_file outfile]\n", up_down_edge);
return 0;
}
ro_degree = atoi(argv[3]);
if(ro_degree < 0 || ro_degree > 360) {
printf("input error,ratation error %d, use [couplet [1~24] interval[1~24] rotation[0~360] in_file outfile]\n", ro_degree);
return 0;
}
sprintf(input_name, "%s", argv[4]);
QFileInfo fileInput(input_name);
if(!fileInput.exists()){
printf("input error,%s not exist\n", input_name);
return 0;
}
sprintf(output_name, "%s", argv[5]);
sprintf(cmd, "touch %s", output_name);
system(cmd);
QFileInfo fileOutput(output_name);
if(!fileOutput.exists()){
printf("out error,not permit to create %s\n", output_name);
return 0;
}
#endif
#ifdef USE_IMG_METHOD
QImage front_pic(input_name);
dot_per_meter_x = front_pic.dotsPerMeterX();
dot_per_meter_y = front_pic.dotsPerMeterY();
matrix.rotate(ro_degree);
front_pic = front_pic.transformed(matrix);
image_w = front_pic.width();
image_h = front_pic.height();
rate = (float)set_size/(float)REC_MAX_PAPER_WIDHT;
set_background_width = REC_MAX_PIC_WIDTH;
if(ro_degree/45 > 0) {
image_w /= 1.42;
image_h /= 1.42;
}
extra_size = up_down_edge*96/2.54;
set_background_height = rate * image_h + extra_size*2;
set_front_width = rate * image_w;
set_front_height = rate * image_h;
front_pic = front_pic.scaledToWidth(set_front_width);
QImage background_pic(set_background_width, set_background_height, QImage::Format_ARGB32);
background_pic.fill(Qt::white);
QImage out_pic = createImageWithOverlay(background_pic, front_pic,
(set_background_width - set_front_width)/2, (set_background_height - set_front_height)/2);
//printf("dotx:%d, doty:%d, dot_per_meter_x:%d, dot_per_meter_y:%d\n", out_pic.dotsPerMeterX(), out_pic.dotsPerMeterY(), dot_per_meter_x, dot_per_meter_y);
out_pic.setDotsPerMeterX(dot_per_meter_x);
out_pic.setDotsPerMeterY(dot_per_meter_y);
out_pic.save(output_name, "jpg");
//printf("dotx:%d, doty:%d\n", out_pic.dotsPerMeterX(), out_pic.dotsPerMeterY());
long end = timestamp();
printf("{imgscale}:[%s->%s](input(%0.0f, %0.0f), scale to(%0.2f, %0.2f), rate(%0.2f), bg(%0.2f, %0.2f))[%ld]ms\n",
input_name, output_name,
image_w, image_h, set_front_width, set_front_height, rate, set_background_width, set_background_height, end - start);
#ifdef DEBUG_SHOW
label.setPixmap(QPixmap::fromImage(out_pic));
label.setFixedSize(set_background_width, set_background_height);
label.show();
return a.exec();
#else
return 0;
#endif
#else
QPixmap front_pic(input_name);
image_w = front_pic.width();
image_h = front_pic.height();
matrix.rotate(ro_degree);
front_pic = front_pic.transformed(matrix);
rate = (float)set_size/(float)REC_MAX_PAPER_WIDHT;
set_background_width = REC_MAX_PIC_WIDTH;
set_background_height = rate * image_h;
set_front_width = rate * image_w;
front_pic = front_pic.scaledToWidth(set_front_width);
set_front_height = rate * image_h;
QPixmap background_pic(set_background_width, set_background_height);
background_pic.fill(Qt::white);
QPixmap out_pic = QPixmap(set_background_width, set_background_height);
QPainter painter(&out_pic);
//1.畫背景
painter.drawPixmap(0, 0, set_background_width, set_background_height, background_pic);
//2.畫前景
painter.drawPixmap((set_background_width - set_front_width)/2, 0, set_front_width, set_front_height, front_pic);
//3.保存
out_pic.save(output_name, "jpg");
long end = timestamp();
printf("{imgscale}:[%s->%s](input(%0.0f, %0.0f), scale to(%0.2f, %0.2f), rate(%0.2f), bg(%0.2f, %0.2f))[%ld]ms\n",
input_name, output_name,
image_w, image_h, set_front_width, set_front_height, rate, set_background_width, set_background_height, end - start);
#ifdef DEBUG_SHOW
label.setPixmap(out_pic);
label.setFixedSize(set_background_width, set_background_height);
label.show();
return a.exec();
#else
return 0;
#endif
#endif
}
放入另外一個沒有安裝linux的系統時,所需的庫結構機shell腳本
需要png,jpeg,libicu48庫及qt編譯後的庫
couplet.sh
#!/bin/sh
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wwwroot/couplet_shell/lib:/home/wwwroot/couplet_shell/libicutu
export QT_PLUGIN_PATH=/home/wwwroot/couplet_shell/plugins
echo $1 $2 $3 $4
./couplet $1 $2 $3 $4