⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imageview.cc

📁 c++的guiQt做的开发
💻 CC
📖 第 1 页 / 共 2 页
字号:
void ImageView::updateFullScreen() { applyZoom();}/** Update data_rect*/void ImageView::setDataRect() { //Get image dimensions int dx=image->x(); int dy=image->y(); //Get image screen dimensions (may differ if zoom is set) int screen_dx=dx*zoom/100; int screen_dy=dy*zoom/100; int x=d->width(); int y=d->height(); int wx=x; int wy=dy*wx/dx; if (wy>y) {  wy=y;  wx=dx*wy/dy; } if (isSet("scale")) {  if (!isSet("center")) {   data_rect=QRect(0,0,wx,wy);  } else {   data_rect=QRect(max((x-wx)/2,0),max((y-wy)/2,0),wx,wy);  } } else {  if (!isSet("center")) {   data_rect=QRect(0,0,screen_dx,screen_dy);  } else {   data_rect=QRect(max((x-screen_dx)/2,0),max((y-screen_dy)/2,0),screen_dx,screen_dy);  } }}/** Repaint the image using given painter and size of output window @param x width of output window @param y height of output window @param p QPainter to use @param src Which part of image to repaint (when not in fullscreen)*/void ImageView::repaint(int x,int y,QPainter &p,const QRect &src) { if (isSet("antialias")) {  //Set antialiasing  p.setRenderHint(QPainter::SmoothPixmapTransform,true); } p.setPen(Qt::blue); QBrush black(QColor(0,0,0)); if (!image) {  //No image is loaded  p.drawRect(0,0,x-1,y-1);  p.fillRect(1,1,x-2,y-2,black);  p.drawText(0,0,x,y,Qt::AlignVCenter | Qt::AlignCenter,tr("No image loaded"));  return; } if (image->x()<=0 || image->y()<=0) {  //Invalid image is loaded  p.drawRect(0,0,x-1,y-1);  p.fillRect(1,1,x-2,y-2,black);  p.drawText(0,0,x,y,Qt::AlignVCenter | Qt::AlignCenter,tr("Invalid image"));  return; } //Rectangle specifying entire window QRect wnd=QRect(0,0,x,y); //Determine target rectangle at screen //Update data rectangle for mouse navigation setDataRect(); //Repaint stripes around image if needed if (data_rect.left()>src.left()) {  //repaint stripe on left  QRect tmp(0,0,data_rect.left(),y);  p.fillRect(tmp & src,black); } if (data_rect.right()<src.right()) {  //repaint on right  QRect tmp(data_rect.right(),0,x-data_rect.right(),y);  p.fillRect(tmp & src,black); } if (data_rect.top()>src.top()) {  //repaint on top  QRect tmp(data_rect.left(),0,data_rect.width(),data_rect.top());  p.fillRect(tmp & src,black); } if (data_rect.bottom()<src.bottom()) {  //repaint on bottom  QRect tmp(data_rect.left(),data_rect.bottom(),data_rect.width(),y-data_rect.bottom());  p.fillRect(tmp & src,black); } if (isSet("scale")) {  //Show scaled to window  //Set target to data rectangle  QRect target=data_rect;  //Draw entire image scaled  QRect source(0,0,image->x(),image->y());  image->draw(&p,source,target); } else {  //No scaling - show 1:1 or show with arbitrary zoom  //Cut out anything outside the actual image  QRect target=src & data_rect;  if (!target.isEmpty()) {  //Is there anything left to draw?   if (zoom==100) {    //No resizing - copy the image    int ix=target.left()-data_rect.left();    int iy=target.top()-data_rect.top();    int isx=target.width();    int isy=target.height();    QRect source(ix,iy,isx,isy);    //Paint it    image->draw(&p,source,target);   } else {//#if QT_VERSION < 0x040200    //Partial workaround for rounding errors (QT 4.1.x or earlier)    target.setWidth(target.width()+1);    target.setHeight(target.height()+1);    target=target & data_rect;//#endif    //Draw part of image    double fx=(double)(target.left()-data_rect.left())*100.0/(double)zoom;    double fy=(double)(target.top()-data_rect.top())*100.0/(double)zoom;    double fsx=(double)target.width()*100.0/(double)zoom;    double fsy=(double)target.height()*100.0/(double)zoom;//    cout << fx << "," << fy << " " << fsx << "x" << fsy << endl;/*#if QT_VERSION >= 0x040200    QRect sourcebound((int)floor(fx),(int)floor(fy),(int)ceil(fsx),(int)ceil(fsy));    //This code is correct in Qt4.2. Qt4.1 can't work with subpixel precision on input    QRectF source(fx,fy,fsx,fsy);    //Paint it    image->draw(&p,sourcebound,target,source);#else*/    //Workaround for QT 4.1.x    //This code is "most correct"    QRect sourcebound((int)floor(fx),(int)floor(fy),(int)ceil(fsx+frac(fx)),(int)ceil(fsy+frac(fy)));    //Recalculate target from sourcebound (to avoid painting non-integer number of pixels from source)    target.setLeft(sourcebound.left()*zoom/100+data_rect.left());    target.setTop(sourcebound.top()*zoom/100+data_rect.top());    target.setWidth(sourcebound.width()*zoom/100);    target.setHeight(sourcebound.height()*zoom/100);    target=target & data_rect;    //Paint it    image->draw(&p,sourcebound,target);    //Perfectly accurate, but insanely slow solution    //QRect source(0,0,dx,dy);    //p.setClipRect(target);    //image->draw(&p,source,data_rect);//#endif   }  } }}/** Cancel any picks (coordinates, pixel intensity) that may be in progress Should be called before setting any picking mode and setting up own signal for it */void ImageView::cancelPicks() { if (mode==view) return; //nothing to cancel emit cancelledPick(); setMode(view);}/** Scroll the area by x pixels down and y pixels to the right @param x How many pixels to sroll to down @param y How many pixels to sroll to right*/void ImageView::scrollBy(int x,int y) { QScrollBar *h=horizontalScrollBar(); QScrollBar *v=verticalScrollBar(); h->setValue(h->value()+x); v->setValue(v->value()+y);}/** Handler called when key is pressed @param e event data*/void ImageView::keyPressEvent(QKeyEvent *e) { if (image) {  int key=e->key();  switch (key) {   case Qt::Key_Escape:    cancelPicks();    break;   case Qt::Key_Up:    scrollBy(0,-16);    break;   case Qt::Key_Down:    scrollBy(0,16);    break;   case Qt::Key_Left:    scrollBy(-16,0);    break;   case Qt::Key_Right:    scrollBy(16,0);    break;   case Qt::Key_Home:    scrollBy(-QWIDGETSIZE_MAX,0);    break;   case Qt::Key_End:    scrollBy(QWIDGETSIZE_MAX,0);    break;   case Qt::Key_PageUp:    scrollBy(0,-height());    break;   case Qt::Key_PageDown:    scrollBy(0,height());    break;   case '+':   case '=':    zoomStep(true);    break;   case '-':    zoomStep(false);    break;   default:    return;  }  return; } e->ignore();}/** Changes zoom to given percentage @param nzoom New zoom, in percent*/void ImageView::setZoom(int nzoom) { zoom=nzoom; applyZoom();}/** Fix zoom value to be within allowed limits and apply new zoom value*/void ImageView::applyZoom() { if (zoom<MIN_ZOOM) zoom=MIN_ZOOM; if (zoom>MAX_ZOOM) zoom=MAX_ZOOM; update();//Will update data_rect if (selection.isValid()) {  setDataRect();  d->moveRubberBand(selectionFromImageCoords(selection)); } emit zoomChanged(zoom);}/** Changes zoom in given direction @param steps Number of steps to zoom in (positive) or out (negative)*/void ImageView::zoomSteps(int steps) { if (!steps) return; //Zero? while (steps<0) { // Zoom -N  zoomStepInternal(false);  steps++;  if (zoom<MIN_ZOOM) break;//Too much zoom } while (steps>0) { // Zoom +N  zoomStepInternal(true);  steps--;  if (zoom>MAX_ZOOM) break;//Too much zoom } applyZoom();}/** Changes zoom in given direction @param zoomIn True if zoom in, else zoom out*/void ImageView::zoomStep(bool zoomIn) { zoomStepInternal(zoomIn); applyZoom();}/** Changes zoom in given direction without applying it @param zoomIn True if zoom in, else zoom out*/void ImageView::zoomStepInternal(bool zoomIn) { int step=10; if (!zoomIn) {  if (zoom<=50) step=5;  if (zoom<=20) step=2;  if (zoom<=10) step=1;  if (zoom>200) step=25;  if (zoom>500) step=100;  if (zoom>1000) step=200;  if (zoom>2000) step=500;  zoom-=step; } else {  if (zoom<50) step=5;  if (zoom<20) step=2;  if (zoom<10) step=1;  if (zoom>=200) step=25;  if (zoom>=500) step=100;  if (zoom>=1000) step=200;  if (zoom>=2000) step=500;  zoom+=step; }}/** Handler called when key is released @param e event data*/void ImageView::keyReleaseEvent(QKeyEvent *e) { e->ignore();}/** Handler called when mouse is moved over the widget @param e event data*/void ImageView::mouseMoveEvent(QMouseEvent *e) { if (!image) {  e->ignore();  return; } int mx=e->x(); int my=e->y(); if (e->buttons() & Qt::RightButton) {  //right mouse button pressed  scrollBy(mouse_ex-mx,mouse_ey-my);  mouse_ex=mx;  mouse_ey=my; }}/** Return string representation of channel count @param c number of channels*/QString ImageView::channelsToString(int c) { if (c==1) return "L";		//luminosity (greyscale) if (c==2) return "LA";		//luminosity (greyscale)+alpha if (c==3) return "RGB";	//RGB if (c==4) return "RGBA";	//RGB+Alpha return QString("(%1C)").arg(c);}/** Handler called when mouse is moved over the widget @param e event data*/void ImageView::mouseCoordEvent(QMouseEvent *e) { if (!image) {  e->ignore();  return; } int mx=e->x(); int my=e->y(); QString value=""; if (!(mx<data_rect.x() || my<data_rect.y() || mx>data_rect.right() || my>data_rect.bottom())) {  // Mouse move within the image  mx-=data_rect.x();  my-=data_rect.y();  mouse_x=mx*image->x()/data_rect.width();  mouse_y=my*image->y()/data_rect.height();  int c=image->channels();  value=channelsToString(c);  value+="=";   for (int i=0;i<c;i++) {   //Image values   value+=QString::number(image->value(mouse_x,mouse_y,i));   if (i<c-1) value+=",";  }  value+=" (#";  for (int i=0;i<c;i++) {   //Image values in hex   value+=image->valueHex(mouse_x,mouse_y,i);    }  value+=")";  //Mouse coords  value=QString("[")+QString::number(mouse_x)+","+QString::number(mouse_y)+"] "+value; } if (!selectionText.isNull()) {  emit selectionInfo(selectionText); } else {  emit selectionInfo(""); } emit info(value);}/** Mouse press handler @param e event data */void ImageView::mousePressEvent(QMouseEvent *e) { if (!image) {  e->ignore();  return; } if (e->button()==Qt::LeftButton) {  if (mode==crosshair) {   setMode(view);   return;  } } if (e->button()==Qt::RightButton) {#if QT_VERSION >= 0x040200  //Only Qt 4.2 or newer  d->setCursor(Qt::ClosedHandCursor);#else  d->setCursor(Qt::SizeAllCursor);#endif  mouse_ex=e->x();  mouse_ey=e->y(); } else {  e->ignore(); }}/** Handler called when one of the mouse buttons is released @param e event data*/void ImageView::mouseReleaseEvent(QMouseEvent *e) { // "reset" current mode setMode(mode); e->ignore();}/** Handler called when wheel on the mouse is scrolled @param e event data*/void ImageView::wheelEvent (QWheelEvent *e) { if (!image) return; int z=e->delta()/4; scrollBy(0,-z); update();}/** default destructor */ImageView::~ImageView() { if (image) delete image;}} // namespace gui

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -