/* * zkWidget.cpp * * Created on: Jul 2, 2013 * Author: yiyu * QQ:1036184468 * Descriptoin: */ #include "zkWidget.h" #include #include #include #include #include "SysPara.h" zkWidget::zkWidget(QWidget *parent):QWidget(parent){ memset(pointMap,0,sizeof(pointMap)); heightPoint = 0; widthPoint = 0; scale = 16; currXpos = 0; currYpos = 0; modified = false; } zkWidget::~zkWidget(){ } void zkWidget::paintEvent(QPaintEvent *event){ QPainter painter(this); QRect rect = event->rect(); int x = (int)(rect.x()/scale); int y = (int)(rect.y()/scale); int x_ = rect.x() + rect.width(); int y_ = rect.y() + rect.height(); int last_x = x_/scale; int last_y = y_/scale; //qDebug() << "x:" << rect.x() << "y:" << rect.y() << "width:" << rect.width() << "heigh:" << rect.height(); for(int i = x; i < widthPoint && i <= last_x; i++){ for(int j = y; j < heightPoint && j <= last_y; j++){ QPen pen; int width = 0; if(currXpos == i && currYpos == j){ width = (scale>4)?2:1; pen.setColor(QColor(Qt::red)); } else { width = (scale > 3)?1:0; pen.setColor(QColor(Qt::gray)); } pen.setWidth(width); painter.setPen(width?pen:Qt::NoPen); if(pointMap[i*MAX_PIC_WIDGET_HEIGHT + j]){ painter.setBrush(QColor(Qt::black)); } else{ painter.setBrush(QColor(Qt::white)); } painter.drawRect(i*scale + width,j*scale + width,scale - 2*width,scale - 2*width); // } } } void zkWidget::mousePressEvent ( QMouseEvent * event ){ int x = (int )(event->x()/(scale)); int y = (int )(event->y()/scale); if(x < widthPoint && y < heightPoint){ int oriX = currXpos; int oriY = currYpos; currXpos = x; currYpos = y; pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = pointMap[x*MAX_PIC_WIDGET_HEIGHT + y]?0:1; update(oriX*scale,oriY*scale,scale,scale); //将原来的焦点去掉 update(x*scale,y*scale,scale,scale); modified = true; emit picWidgetModify(widthPoint,heightPoint); } } void zkWidget::currPositionMove(int shiftX,int shiftY,bool moveAllPic,bool trimPic,bool expandPic) { if((widthPoint && heightPoint) || expandPic){ if(moveAllPic){ shiftX = - shiftX; shiftY = -shiftY; int init_x = (shiftX < 0)?(widthPoint - 1):0; int end_x = (shiftX >= 0)?(widthPoint):-1; int step_x = (shiftX < 0)?-1:1; int init_y = (shiftY < 0)?(heightPoint - 1):0; int end_y = (shiftY >= 0)?(heightPoint):- 1; int step_y = (shiftY < 0)?-1:1;; for(int x = init_x; x != end_x; x+= step_x){ for(int y = init_y; y != end_y; y+= step_y){ int new_x = x + shiftX; int new_y = y + shiftY; if(new_x < 0 || new_x >= widthPoint || new_y < 0 || new_y >= heightPoint){ //pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = trueColorEnable?backGround.rgba():0xffffffff; pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = 0x00000000; } else pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = pointMap[new_x*MAX_PIC_WIDGET_HEIGHT + new_y]; } } update(); } else if(trimPic){ int diffX = (widthPoint > qAbs(shiftX))?qAbs(shiftX):widthPoint; int diffY = (heightPoint > qAbs(shiftY))?qAbs(shiftY):heightPoint; if(shiftX > 0){ currPositionMove(- diffX,0,true,false,false); } if(shiftY > 0){ currPositionMove(0,-diffY,true,false,false); } heightPoint -= diffY; widthPoint -= diffX; resize(widthPoint*scale,heightPoint*scale); update(); } else if(expandPic){ int diffX = ((MAX_PIC_WIDGET_WIDTH - widthPoint) > qAbs(shiftX))?qAbs(shiftX):(MAX_PIC_WIDGET_WIDTH - widthPoint); int diffY = ((MAX_PIC_WIDGET_HEIGHT - heightPoint) > qAbs(shiftY))?qAbs(shiftY):(MAX_PIC_WIDGET_HEIGHT - heightPoint); for(int y = 0; y < heightPoint + diffY;y ++){ for(int x = 0; x < widthPoint + diffX; x++){ if(y < heightPoint && x < widthPoint){ } else { //pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = trueColorEnable?backGround.rgba():0xffffffff; pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = 0x0000000; } } } heightPoint += diffY; widthPoint += diffX; resize(widthPoint*scale,heightPoint*scale); if(shiftX < 0){ currPositionMove(diffX,0,true,false,false); } if(shiftY < 0){ currPositionMove(0,diffY,true,false,false); } //qDebug() << "diffX:" << diffX << "diffY:" << diffY << "heightPoint:" << heightPoint << "widthPoint" << widthPoint; update(); } else { int oriX = currXpos; int oriY = currYpos; currXpos += shiftX; currYpos += shiftY; currXpos = (currXpos >= 0)?(currXpos%widthPoint):(currXpos + widthPoint); currYpos = (currYpos >= 0)?(currYpos%heightPoint):(currYpos + heightPoint); update(oriX*scale,oriY*scale,scale,scale); update(currXpos*scale,currYpos*scale,scale,scale); } emit picWidgetModify(widthPoint,heightPoint); } } void zkWidget::ensureCurrPos(){ if(heightPoint && widthPoint){ int x = currXpos; int y = currYpos; pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = pointMap[x*MAX_PIC_WIDGET_HEIGHT + y]?0:1; update(x*scale,y*scale,scale,scale); modified = true; emit picWidgetModify(widthPoint,heightPoint); } } bool zkWidget::isModified(){ return modified; } void zkWidget::setModified(bool m){ modified = m; } int zkWidget::getHeight(){ return heightPoint; } int zkWidget::getWidth(){ return widthPoint; } int zkWidget::getScaleValue(){ return scale; } void zkWidget::initWidget(int w,int h){ scale = 30; if(parentWidget()){ QWidget *widget = parentWidget(); int width = widget->geometry().width(); int height = widget->geometry().height(); int scaleX = w?width/w:width; //不要除零 int scaleY = h?height/h:height; scaleX = scaleX > 0?scaleX:1; //scale不能小于零 scaleY = scaleY > 0?scaleY:1; scale = scaleX > scaleY?scaleY:scaleX; } currXpos = 0; currYpos = 0; memset(pointMap,0,sizeof(pointMap)); resizeWidget(w,h); modified = false; } void zkWidget::resizeWidget(int w,int h){ if(w > MAX_PIC_WIDGET_WIDTH || h > MAX_PIC_WIDGET_HEIGHT){ QMessageBox::warning(0,tr("警告"),tr("最大支持宽度:%1 高度:%2 当前请求:%3 x %4").arg(MAX_PIC_WIDGET_WIDTH).arg(MAX_PIC_WIDGET_HEIGHT).arg(w).arg(h)); widthPoint = (w > MAX_PIC_WIDGET_WIDTH)?MAX_PIC_WIDGET_WIDTH:w; heightPoint = (h > MAX_PIC_WIDGET_HEIGHT)?MAX_PIC_WIDGET_HEIGHT:h; } else{ widthPoint = w; heightPoint = h; } resize(w*scale,h*scale); update(); } void zkWidget::enlargeDisplay(){ if(scale < (1<<10)){ scale = scale + ((scale>2)?scale/2:1); resize(widthPoint*scale,heightPoint*scale); update(); } } void zkWidget::reduceDisplay(){ if(scale > 1){ scale = scale - ((scale > 2)?scale/3:1); resize(widthPoint*scale,heightPoint*scale); update(); } } void zkWidget::setScale(int scale){ if(scale > 1) this->scale = scale; else scale = 1; resize(widthPoint*scale,heightPoint*scale); update(); } void zkWidget::loadImage(QString filename,bool forceSize,QString charStr,QFont *font){ if((widthPoint == 0 || heightPoint == 0) && forceSize){ QMessageBox::warning(0,"警告","请新创建建图片"); } else { bool forceForegroundBackgroundColorFill = false; QImage img; QFile file(filename); if(!filename.isEmpty() && file.exists()) img.load(filename); else if(charStr.size()){ if(font){ QFontMetrics fontMetrics(*font); //int rightBearing = fontMetrics.rightBearing(QChar(unicode)); //int leftBearing = fontMetrics.leftBearing(QChar(unicode)); int width = forceSize?widthPoint:(fontMetrics.width(charStr)) ; int height = forceSize?heightPoint:(fontMetrics.ascent() + fontMetrics.descent()); if(width == 0){ QMessageBox::warning(0,"警告",QString("字串:%1 在字体%2中不存在").arg(charStr).arg(font->family())); return ; } QSize size(width,height); QImage image(size,QImage::Format_ARGB32); img = image; img.fill(0xffffffff); QPainter painter(&img); painter.setFont(*font); painter.drawText(QPoint(0,fontMetrics.ascent()),charStr); forceForegroundBackgroundColorFill = true; } } if(img.isNull()){ QMessageBox::warning(0,"Warning",QString("File:%1 open failed").arg(filename)); } else { int w = img.rect().width(); int h = img.rect().height(); memset(pointMap,0,sizeof(pointMap)); if(!forceSize){ widthPoint = (w > MAX_PIC_WIDGET_WIDTH)?MAX_PIC_WIDGET_WIDTH:w; heightPoint = (h > MAX_PIC_WIDGET_HEIGHT)?MAX_PIC_WIDGET_HEIGHT:h; resize(widthPoint*scale,heightPoint*scale); } QRgb argb = 0; for(int i = 0; i < widthPoint;i++){ for(int j = 0; j < heightPoint ; j++){ bool pixelVisible = false; int init_x = i*w/widthPoint; int end_x = (w >= widthPoint)?(i + 1)*w/widthPoint:init_x + 1; int init_y = j*h/heightPoint; int end_y = (h >= heightPoint)?(j + 1)*h/heightPoint:init_y + 1; for(int l = init_x; l < end_x; l++){ for(int m = init_y; m < end_y; m ++){ argb = img.pixel(l,m); //qDebug() << "i:" << i << "j" << j << " " << QString::number(argb,16); if(argb == 0xffffffff) //节约时钟周期 continue; if((argb & 0xff000000) && (((argb&0xff0000) < 0x800000) || ((argb&0xff00) < 0x8000) || ((argb&0xff) < 0x80))){ pixelVisible = true; break; } } if(pixelVisible) break; } if(pixelVisible) pointMap[i*MAX_PIC_WIDGET_HEIGHT + j] = 1; } } update(); setModified(false); } } } void zkWidget::saveImage(QString filename){ if(widthPoint == 0 || heightPoint == 0){ QMessageBox::warning(0,tr("警告"),tr("请新创建建图片")); } else { QSize size(widthPoint,heightPoint); QImage image(size,QImage::Format_ARGB32); image.fill(qRgba(0,0,0,0xff)); for(int i = 0 ; i < widthPoint; i++){ for(int j = 0; j < heightPoint; j++){ image.setPixel(i,j,pointMap[i*MAX_PIC_WIDGET_HEIGHT + j]?0xff000000:0xffffffff); } } filename = DOC_ROOT_DIR+ QFileInfo(filename).baseName()+".jpg"; image.save( filename ); } setModified(false); }