コード例 #1
0
ファイル: qgsmaprenderer.cpp プロジェクト: mola/Quantum-GIS
void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
{
  //Lock render method for concurrent threads (e.g. from globe)
  QMutexLocker renderLock( &mRenderMutex );

  //flag to see if the render context has changed
  //since the last time we rendered. If it hasnt changed we can
  //take some shortcuts with rendering
  bool mySameAsLastFlag = true;

  QgsDebugMsg( "========== Rendering ==========" );

  if ( mExtent.isEmpty() )
  {
    QgsDebugMsg( "empty extent... not rendering" );
    return;
  }

  if ( mSize.width() == 1 && mSize.height() == 1 )
  {
    QgsDebugMsg( "size 1x1... not rendering" );
    return;
  }

  QPaintDevice* thePaintDevice = painter->device();
  if ( !thePaintDevice )
  {
    return;
  }

  // wait
  if ( mDrawing )
  {
    QgsDebugMsg( "already rendering" );
    QCoreApplication::processEvents();
  }

  if ( mDrawing )
  {
    QgsDebugMsg( "still rendering - skipping" );
    return;
  }

  mDrawing = true;

  QgsCoordinateTransform* ct;

#ifdef QGISDEBUG
  QgsDebugMsg( "Starting to render layer stack." );
  QTime renderTime;
  renderTime.start();
#endif

  if ( mOverview )
    mRenderContext.setDrawEditingInformation( !mOverview );

  mRenderContext.setPainter( painter );
  mRenderContext.setCoordinateTransform( 0 );
  //this flag is only for stopping during the current rendering progress,
  //so must be false at every new render operation
  mRenderContext.setRenderingStopped( false );

  //calculate scale factor
  //use the specified dpi and not those from the paint device
  //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene)
  double sceneDpi = mScaleCalculator->dpi();
  double scaleFactor = 1.0;
  if ( mOutputUnits == QgsMapRenderer::Millimeters )
  {
    if ( forceWidthScale )
    {
      scaleFactor = *forceWidthScale;
    }
    else
    {
      scaleFactor = sceneDpi / 25.4;
    }
  }
  double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi;
  if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor )
  {
    mRenderContext.setRasterScaleFactor( rasterScaleFactor );
    mySameAsLastFlag = false;
  }
  if ( mRenderContext.scaleFactor() != scaleFactor )
  {
    mRenderContext.setScaleFactor( scaleFactor );
    mySameAsLastFlag = false;
  }
  if ( mRenderContext.rendererScale() != mScale )
  {
    //add map scale to render context
    mRenderContext.setRendererScale( mScale );
    mySameAsLastFlag = false;
  }
  if ( mLastExtent != mExtent )
  {
    mLastExtent = mExtent;
    mySameAsLastFlag = false;
  }

  mRenderContext.setLabelingEngine( mLabelingEngine );
  if ( mLabelingEngine )
    mLabelingEngine->init( this );

  // know we know if this render is just a repeat of the last time, we
  // can clear caches if it has changed
  if ( !mySameAsLastFlag )
  {
    //clear the cache pixmap if we changed resolution / extent
    QSettings mySettings;
    if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
    {
      QgsMapLayerRegistry::instance()->clearAllLayerCaches();
    }
  }

  QgsOverlayObjectPositionManager* overlayManager = overlayManagerFromSettings();
  QList<QgsVectorOverlay*> allOverlayList; //list of all overlays, used to draw them after layers have been rendered

  // render all layers in the stack, starting at the base
  QListIterator<QString> li( mLayerSet );
  li.toBack();

  QgsRectangle r1, r2;

  while ( li.hasPrevious() )
  {
    if ( mRenderContext.renderingStopped() )
    {
      break;
    }

    // Store the painter in case we need to swap it out for the
    // cache painter
    QPainter * mypContextPainter = mRenderContext.painter();

    QString layerId = li.previous();

    QgsDebugMsg( "Rendering at layer item " + layerId );

    // This call is supposed to cause the progress bar to
    // advance. However, it seems that updating the progress bar is
    // incompatible with having a QPainter active (the one that is
    // passed into this function), as Qt produces a number of errors
    // when try to do so. I'm (Gavin) not sure how to fix this, but
    // added these comments and debug statement to help others...
    QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" );

    //emit drawingProgress(myRenderCounter++, mLayerSet.size());
    QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );

    if ( !ml )
    {
      QgsDebugMsg( "Layer not found in registry!" );
      continue;
    }

    QgsDebugMsg( QString( "layer %1:  minscale:%2  maxscale:%3  scaledepvis:%4  extent:%5" )
                 .arg( ml->name() )
                 .arg( ml->minimumScale() )
                 .arg( ml->maximumScale() )
                 .arg( ml->hasScaleBasedVisibility() )
                 .arg( ml->extent().toString() )
               );

    if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mScale && mScale < ml->maximumScale() ) || mOverview )
    {
      connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );

      //
      // Now do the call to the layer that actually does
      // the rendering work!
      //

      bool split = false;

      if ( hasCrsTransformEnabled() )
      {
        r1 = mExtent;
        split = splitLayersExtent( ml, r1, r2 );
        ct = new QgsCoordinateTransform( ml->crs(), *mDestCRS );
        mRenderContext.setExtent( r1 );
        QgsDebugMsg( "  extent 1: " + r1.toString() );
        QgsDebugMsg( "  extent 2: " + r2.toString() );
        if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer
        {
          continue;
        }
      }
      else
      {
        ct = NULL;
      }

      mRenderContext.setCoordinateTransform( ct );

      //decide if we have to scale the raster
      //this is necessary in case QGraphicsScene is used
      bool scaleRaster = false;
      QgsMapToPixel rasterMapToPixel;
      QgsMapToPixel bk_mapToPixel;

      if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 )
      {
        scaleRaster = true;
      }


      //create overlay objects for features within the view extent
      if ( ml->type() == QgsMapLayer::VectorLayer && overlayManager )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl )
        {
          QList<QgsVectorOverlay*> thisLayerOverlayList;
          vl->vectorOverlays( thisLayerOverlayList );

          QList<QgsVectorOverlay*>::iterator overlayIt = thisLayerOverlayList.begin();
          for ( ; overlayIt != thisLayerOverlayList.end(); ++overlayIt )
          {
            if (( *overlayIt )->displayFlag() )
            {
              ( *overlayIt )->createOverlayObjects( mRenderContext );
              allOverlayList.push_back( *overlayIt );
            }
          }

          overlayManager->addLayer( vl, thisLayerOverlayList );
        }
      }

      // Force render of layers that are being edited
      // or if there's a labeling engine that needs the layer to register features
      if ( ml->type() == QgsMapLayer::VectorLayer )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->isEditable() ||
             ( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) )
        {
          ml->setCacheImage( 0 );
        }
      }

      QSettings mySettings;
      if ( ! split )//render caching does not yet cater for split extents
      {
        if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
        {
          if ( !mySameAsLastFlag || ml->cacheImage() == 0 )
          {
            QgsDebugMsg( "Caching enabled but layer redraw forced by extent change or empty cache" );
            QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(),
                                            mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
            mypImage->fill( 0 );
            ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you
            QPainter * mypPainter = new QPainter( ml->cacheImage() );
            // Changed to enable anti aliasing by default in QGIS 1.7
            if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
            {
              mypPainter->setRenderHint( QPainter::Antialiasing );
            }
            mRenderContext.setPainter( mypPainter );
          }
          else if ( mySameAsLastFlag )
          {
            //draw from cached image
            QgsDebugMsg( "Caching enabled --- drawing layer from cached image" );
            mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
            disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
            //short circuit as there is nothing else to do...
            continue;
          }
        }
      }

      if ( scaleRaster )
      {
        bk_mapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor );
        rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor );
        mRenderContext.setMapToPixel( rasterMapToPixel );
        mRenderContext.painter()->save();
        mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
      }

      if ( !ml->draw( mRenderContext ) )
      {
        emit drawError( ml );
      }
      else
      {
        QgsDebugMsg( "Layer rendered without issues" );
      }

      if ( split )
      {
        mRenderContext.setExtent( r2 );
        if ( !ml->draw( mRenderContext ) )
        {
          emit drawError( ml );
        }
      }

      if ( scaleRaster )
      {
        mRenderContext.setMapToPixel( bk_mapToPixel );
        mRenderContext.painter()->restore();
      }

      if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
      {
        if ( !split )
        {
          // composite the cached image into our view and then clean up from caching
          // by reinstating the painter as it was swapped out for caching renders
          delete mRenderContext.painter();
          mRenderContext.setPainter( mypContextPainter );
          //draw from cached image that we created further up
          mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
        }
      }
      disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
    }
    else // layer not visible due to scale
    {
コード例 #2
0
ファイル: clipobject.cpp プロジェクト: nci/drishti
void
ClipObject::loadCaption(QString ct, QFont cf,
			QColor cc, QColor chc)
{
  m_captionText = ct;
  m_captionFont = cf;
  m_captionColor = cc;
  m_captionHaloColor = chc;

  if (m_captionText.isEmpty())
    {
      m_captionPresent = false;
      return;
    }

  QFontMetrics metric(m_captionFont);
  int mde = metric.descent();
  int fht = metric.height();
  int fwd = metric.width(m_captionText)+2;

  //-------------------
  QImage bImage = QImage(fwd, fht, QImage::Format_ARGB32);
  bImage.fill(0);
  {
    QPainter bpainter(&bImage);
    // we have image as ARGB, but we want RGBA
    // so switch red and blue colors here itself
    QColor penColor(m_captionHaloColor.blue(),
		    m_captionHaloColor.green(),
		    m_captionHaloColor.red());
    // do not use alpha(),
    // opacity will be modulated using clip-plane's opacity parameter  
    bpainter.setPen(penColor);
    bpainter.setFont(m_captionFont);
    bpainter.drawText(1, fht-mde, m_captionText);

    uchar *dbits = new uchar[4*fht*fwd];
    uchar *bits = bImage.bits();
    memcpy(dbits, bits, 4*fht*fwd);

    for(int i=2; i<fht-2; i++)
      for(int j=2; j<fwd-2; j++)
	{
	  for (int k=0; k<4; k++)
	    {
	      int sum = 0;
	      
	      for(int i0=-2; i0<=2; i0++)
		for(int j0=-2; j0<=2; j0++)
		  sum += dbits[4*((i+i0)*fwd+(j+j0)) + k];
	      
	      bits[4*(i*fwd+j) + k] = sum/25;
	    }
	}
    delete [] dbits;
  }
  //-------------------

  QImage cImage = QImage(fwd, fht, QImage::Format_ARGB32);
  cImage.fill(0);
  QPainter cpainter(&cImage);

  // first draw the halo image
  cpainter.drawImage(0, 0, bImage);


  // we have image as ARGB, but we want RGBA
  // so switch red and blue colors here itself
  QColor penColor(m_captionColor.blue(),
		  m_captionColor.green(),
		  m_captionColor.red());
  // do not use alpha(),
  // opacity will be modulated using clip-plane's opacity parameter  
  cpainter.setPen(penColor);
  cpainter.setFont(m_captionFont);
  cpainter.drawText(1, fht-mde, m_captionText);
  m_textureWidth = fwd;
  m_textureHeight = fht;
      
  unsigned char *image = new unsigned char[4*m_textureWidth*m_textureHeight];
  memcpy(image, cImage.bits(), 4*m_textureWidth*m_textureHeight); 

  if (m_imageTex)
    glDeleteTextures(1, &m_imageTex);
  glGenTextures(1, &m_imageTex);

  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_imageTex);
  glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
  glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
	       0,
	       4,
	       m_textureWidth,
	       m_textureHeight,
	       0,
	       GL_RGBA,
	       GL_UNSIGNED_BYTE,
	       image);
  glDisable(GL_TEXTURE_RECTANGLE_ARB);

  delete [] image;

  clearImage();

  m_captionPresent = true;
}
コード例 #3
0
QSizeF QgsSymbolV2LegendNode::drawSymbol( const QgsLegendSettings& settings, ItemContext* ctx, double itemHeight ) const
{
  QgsSymbolV2* s = mItem.symbol();
  if ( !s )
  {
    return QSizeF();
  }

  // setup temporary render context
  QgsRenderContext context;
  context.setScaleFactor( settings.dpi() / 25.4 );
  context.setRendererScale( settings.mapScale() );
  context.setMapToPixel( QgsMapToPixel( 1 / ( settings.mmPerMapUnit() * context.scaleFactor() ) ) );
  context.setForceVectorOutput( true );
  context.setPainter( ctx ? ctx->painter : 0 );

  //Consider symbol size for point markers
  double height = settings.symbolSize().height();
  double width = settings.symbolSize().width();
  double size = 0;
  //Center small marker symbols
  double widthOffset = 0;
  double heightOffset = 0;

  if ( QgsMarkerSymbolV2* markerSymbol = dynamic_cast<QgsMarkerSymbolV2*>( s ) )
  {
    // allow marker symbol to occupy bigger area if necessary
    size = markerSymbol->size() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, s->outputUnit(), s->mapUnitScale() ) / context.scaleFactor();
    height = size;
    width = size;
    if ( width < settings.symbolSize().width() )
    {
      widthOffset = ( settings.symbolSize().width() - width ) / 2.0;
    }
    if ( height < settings.symbolSize().height() )
    {
      heightOffset = ( settings.symbolSize().height() - height ) / 2.0;
    }
  }

  if ( ctx )
  {
    double currentXPosition = ctx->point.x();
    double currentYCoord = ctx->point.y() + ( itemHeight - settings.symbolSize().height() ) / 2;
    QPainter* p = ctx->painter;

    //setup painter scaling to dots so that raster symbology is drawn to scale
    double dotsPerMM = context.scaleFactor();

    int opacity = 255;
    if ( QgsVectorLayer* vectorLayer = dynamic_cast<QgsVectorLayer*>( layerNode()->layer() ) )
      opacity = 255 - ( 255 * vectorLayer->layerTransparency() / 100 );

    p->save();
    p->setRenderHint( QPainter::Antialiasing );
    p->translate( currentXPosition + widthOffset, currentYCoord + heightOffset );
    p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
    if ( opacity != 255 && settings.useAdvancedEffects() )
    {
      //semi transparent layer, so need to draw symbol to an image (to flatten it first)
      //create image which is same size as legend rect, in case symbol bleeds outside its alloted space
      QSize tempImageSize( width * dotsPerMM, height * dotsPerMM );
      QImage tempImage = QImage( tempImageSize, QImage::Format_ARGB32 );
      tempImage.fill( Qt::transparent );
      QPainter imagePainter( &tempImage );
      context.setPainter( &imagePainter );
      s->drawPreviewIcon( &imagePainter, tempImageSize, &context );
      context.setPainter( ctx->painter );
      //reduce opacity of image
      imagePainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
      imagePainter.fillRect( tempImage.rect(), QColor( 0, 0, 0, opacity ) );
      imagePainter.end();
      //draw rendered symbol image
      p->drawImage( 0, 0, tempImage );
    }
    else
    {
      s->drawPreviewIcon( p, QSize( width * dotsPerMM, height * dotsPerMM ), &context );
    }
    p->restore();
  }

  return QSizeF( qMax( width + 2 * widthOffset, ( double ) settings.symbolSize().width() ),
                 qMax( height + 2 * heightOffset, ( double ) settings.symbolSize().height() ) );
}
コード例 #4
0
bool GroundPlaneGenerator::generateGroundPlaneUnit(const QString & boardSvg, QSizeF boardImageSize, const QString & svg, QSizeF copperImageSize, 
												   QStringList & exceptions, QGraphicsItem * board, double res, const QString & color, const QString & layerName,
												   QPointF whereToStart, double blurBy) 
{
	double bWidth, bHeight;
	QImage * image = generateGroundPlaneAux(boardSvg, boardImageSize, svg, copperImageSize, exceptions, board, res, bWidth, bHeight, blurBy);
	if (image == NULL) return false;

	QPoint s(qRound(res * (whereToStart.x() - board->pos().x()) / FSvgRenderer::printerScale()),
			qRound(res * (whereToStart.y() - board->pos().y()) / FSvgRenderer::printerScale()));

	QBitArray redMarker(image->height() * image->width(), false);

	QRgb pixel = image->pixel(s);
	int gray = QGRAY(pixel);
	if (gray <= THRESHOLD) {
		// starting off in bad territory
		delete image;
		return false;
	}

	// step 1 flood fill white to "red" (keep max locations)

	int minY = image->height();
	int maxY = 0;
	int minX = image->width();
	int maxX = 0;
	QList<QPoint> stack;
	stack << s;
	while (stack.count() > 0) {
		QPoint p = stack.takeFirst();

		if (p.x() < 0) continue;
		if (p.y() < 0) continue;
		if (p.x() >= image->width()) continue;
		if (p.y() >= image->height()) continue;
		if (redMarker.testBit(OFFSET(p.x(), p.y(), image))) continue;			// already been here

		QRgb pixel = image->pixel(p);
		int gray = QGRAY(pixel);
		if (gray <= THRESHOLD) continue;			// black; bail

		redMarker.setBit(OFFSET(p.x(), p.y(), image), true);
		if (p.x() > maxX) maxX = p.x();
		if (p.x() < minX) minX = p.x();
		if (p.y() > maxY) maxY = p.y();
		if (p.y() < minY) minY = p.y();

		stack.append(QPoint(p.x() - 1, p.y()));
		stack.append(QPoint(p.x() + 1, p.y()));
		stack.append(QPoint(p.x(), p.y() - 1));
		stack.append(QPoint(p.x(), p.y() + 1));
	}

	//image->save("testPoly1.png");

	// step 2 replace white with black
	image->fill(0);

	// step 3 replace "red" with white
	for (int y = 0; y < image->height(); y++) {
		for (int x = 0; x < image->width(); x++) {
			if (redMarker.testBit(OFFSET(x, y, image))) {
				image->setPixel(x, y, 1);
			}
		}
	}

#ifndef QT_NO_DEBUG
	image->save("testGroundPlaneUnit3.png");
#endif

	scanImage(*image, bWidth, bHeight, GraphicsUtils::StandardFritzingDPI / res, res, color, layerName, true, res / 50, true, QSizeF(.05, .05), 1 / FSvgRenderer::printerScale(), QPointF(0,0));
	delete image;
	return true;
}
コード例 #5
0
QImage * GroundPlaneGenerator::generateGroundPlaneAux(const QString & boardSvg, QSizeF boardImageSize, const QString & svg, QSizeF copperImageSize, 
													QStringList & exceptions, QGraphicsItem * board, double res, double & bWidth, double & bHeight, double blurBy) 
{
	QByteArray boardByteArray;
    QString tempColor("#ffffff");
    if (!SvgFileSplitter::changeColors(boardSvg, tempColor, exceptions, boardByteArray)) {
		return NULL;
	}

	/*
	QFile file0("testGroundFillBoard.svg");
	file0.open(QIODevice::WriteOnly);
	QTextStream out0(&file0);
	out0 << boardByteArray;
	file0.close();
	*/


	QByteArray copperByteArray;
	if (!SvgFileSplitter::changeStrokeWidth(svg, 50, false, copperByteArray)) {
		return NULL;
	}

	/*
	QFile file1("testGroundFillCopper.svg");
	file1.open(QIODevice::WriteOnly);
	QTextStream out1(&file1);
	out1 << copperByteArray;
	file1.close();
	*/

	double svgWidth = res * qMax(boardImageSize.width(), copperImageSize.width()) / FSvgRenderer::printerScale();
	double svgHeight = res * qMax(boardImageSize.height(), copperImageSize.height()) / FSvgRenderer::printerScale();

	QRectF br =  board->sceneBoundingRect();
	bWidth = res * br.width() / FSvgRenderer::printerScale();
	bHeight = res * br.height() / FSvgRenderer::printerScale();
	QImage * image = new QImage(qMax(svgWidth, bWidth), qMax(svgHeight, bHeight), QImage::Format_Mono); //
	image->setDotsPerMeterX(res * GraphicsUtils::InchesPerMeter);
	image->setDotsPerMeterY(res * GraphicsUtils::InchesPerMeter);
	image->fill(0x0);

	QSvgRenderer renderer(boardByteArray);
	QPainter painter;
	painter.begin(image);
	painter.setRenderHint(QPainter::Antialiasing, false);
	renderer.render(&painter, QRectF(0, 0, res * boardImageSize.width() / FSvgRenderer::printerScale(), res * boardImageSize.height() / FSvgRenderer::printerScale()));
	painter.end();

#ifndef QT_NO_DEBUG
	image->save("testGroundFillBoard.png");
#endif

	for (double m = 0; m < .004; m += (1.0 / res)) {
		QList<QPoint> points;
		collectBorderPoints(*image, points);

#ifndef QT_NO_DEBUG
		// for debugging
		double pixelFactor = GraphicsUtils::StandardFritzingDPI / res;
		QPolygon polygon;
		foreach(QPoint p, points) {
			polygon.append(QPoint(p.x() * pixelFactor, p.y() * pixelFactor));
		}

		QList<QPolygon> polygons;
		polygons.append(polygon);
		QPointF offset;
		QString pSvg = makePolySvg(polygons, res, bWidth, bHeight, pixelFactor, "#ffffff", "debug", false,  NULL, QSizeF(0,0), 0, QPointF(0, 0));
#endif

		foreach (QPoint p, points) image->setPixel(p, 0);
	}
コード例 #6
0
ファイル: Project2.cpp プロジェクト: mandary/ComputerVision
/*******************************************************************************
Stitch together two images using the homography transformation
    image1 - first input image
    image2 - second input image
    hom - homography transformation (image1 -> image2)
    homInv - inverse homography transformation (image2 -> image1)
    stitchedImage - returned stitched image
*******************************************************************************/
void MainWindow::Stitch(QImage image1, QImage image2, double hom[3][3], double homInv[3][3], QImage &stitchedImage)
{
    int r, c, i;
    QRgb pixel;
    int ws, hs;
    int w1 = image1.width();
    int h1 = image1.height();
    int w2 = image2.width();
    int h2 = image2.height();
    int cmin = 0;
    int cmax = w1;
    int rmin = 0;
    int rmax = h1;
    double corners[8];

    corners[0] = corners[1] = corners[3] = corners[4] = 0.0;
    corners[2] = corners[6] = (double) w2;
    corners[5] = corners[7] = (double) h2;

    // Compute ws and has by projecting four corners of image2 to image1
    for(i = 0; i < 4; i++) {
        double x, y;
        Project(corners[i * 2], corners[i * 2 + 1], x, y, homInv);
        int r = floor(y + 0.5);
        int c = floor(x + 0.5);
        cmin = cmin > c ? c : cmin;
        cmax = cmax < c ? c : cmax;
        rmin = rmin > r ? r : rmin;
        rmax = rmax < r ? r : rmax;
    }

    ws = cmax - cmin;
    hs = rmax - rmin;

    // Initialize the stitchedImage
    stitchedImage = QImage(ws, hs, QImage::Format_RGB32);
    stitchedImage.fill(qRgb(0,0,0));

    // Warp image1 and image2 to stitchedImage.
    // Copy image1 to stitchedImage
    for(r = 0; r < h1; r++) {
        for(c = 0; c < w1; c++) {
            pixel = image1.pixel(c, r);
            stitchedImage.setPixel(c - cmin, r - rmin, pixel);
        }
    }

    // Project each pixel of stitchedImage onto image2
    // bilinearInterpolate the value
    for(r = 0; r < hs; r++) {
        for(c = 0; c < ws; c++) {
            double x, y; 
            double rgb[3];
            pixel = stitchedImage.pixel(c, r);
            Project((double)(c + cmin), (double)(r + rmin), x, y, hom);
            if(BilinearInterpolation(&image2, x, y, rgb)) {
                stitchedImage.setPixel(c, r, qRgb((int) rgb[0], (int) rgb[1], (int) rgb[2]));
            }

        }
    }

}
コード例 #7
0
void CameraTab::redraw() {
   // cout << "Calling redraw\n";
   QImage image = QImage(IMAGE_COLS, IMAGE_ROWS, QImage::Format_RGB32);
   pointCloud.points.resize(0);
   if(topFrame && botFrame) {
      //display normal image
      for (unsigned int row = 0; row < IMAGE_ROWS; ++row) {
         for (unsigned int col = 0; col < IMAGE_COLS; ++col) {
            QRgb rgb = getRGB(col, row, topFrame, TOP_IMAGE_COLS);
            image.setPixel(col, row, rgb);
            int r, g, b;
            QColor::fromRgb(rgb).getRgb(&r, &g, &b);
            pointCloud.points.push_back(make_pair(qglviewer::Vec(r / 255.0,
                                                                 g / 255.0,
                                                                 b / 255.0),
                                                  qglviewer::Vec
                                       (gety(topFrame, row, col) / 255.0,
                                        getu(topFrame, row, col) / 255.0,
                                        getv(topFrame, row, col) / 255.0)));
         }
      }
   } else {
      image.fill(Qt::darkGray);
   }

   QPixmap imagePixmap = QPixmap(QPixmap::fromImage(image.scaled(IMAGE_COLS/2, IMAGE_ROWS/2)));
   imageLabels[CAMERA]->setPixmap(imagePixmap);

   // Create histograms
   //Histogram RGBHistogram(0x00000000U, 0x00ffffffU);
   YUVHistogram yuvHistogram(0x00000000U, 0x00ffffffU);
   //Histogram redHistogram(0x00U, 0xffU);
   //Histogram greenHistogram(0x00U, 0xffU);
   //Histogram blueHistogram(0x00U, 0xffU);

   // Process image
   for (unsigned int row = 0; row < IMAGE_ROWS; ++row) {
      for (unsigned int col = 0; col < IMAGE_COLS; ++col) {
         unsigned int YUVValue = 0x00ffffff &
                                 ((gety(topFrame, row, col) << 16) |
                                  (getu(topFrame, row, col) << 8) |
                                   getv(topFrame, row, col));

         //RGBHistogram.addDatapoint(getRGB(col, row, currentFrame) & MAX_RGB_VALUE);
         yuvHistogram.addDatapoint(YUVValue);
         //redHistogram.addDatapoint((getRGB(col, row, currentFrame) & RED_MASK) >> 16);
         //greenHistogram.addDatapoint((getRGB(col, row, currentFrame) & GREEN_MASK) >> 8);
         //blueHistogram.addDatapoint(getRGB(col, row, currentFrame) & BLUE_MASK);
      }
   }

/*******************************************************************************
REMOVED FOR EFFICIENCY
   // Print statistics to terminal
   ostringstream ost;
   ost << "RGB Histogram ";
   //RGBHistogram.printStatistics(ost);
   ost << "YUV Histogram ";
   //yuvHistogram.printStatistics(ost);
   ost << "Red Histogram ";
   redHistogram.printStatistics(ost);
   ost << "Green Histogram ";
   greenHistogram.printStatistics(ost);
   ost << "Blue Histogram ";
   blueHistogram.printStatistics(ost);
   // cout << ost.str();
*******************************************************************************/

   // Draw histograms
   //  set initial background of pixmaps
   imagePixmaps[RGB].fill(Qt::darkGray);
   imagePixmaps[YUV].fill(Qt::darkGray);
   imagePixmaps[HSV].fill(Qt::darkGray);
   //  draw each histogram
   //RGBHistogram.drawHistogram(imagePixmaps[RGB], (unsigned int)(IMAGE_COLS/2), (unsigned int)(IMAGE_ROWS/2), Histogram::eRGB);
   yuvHistogram.drawHistogram(imagePixmaps[YUV], (unsigned int)(IMAGE_COLS/2), (unsigned int)(IMAGE_ROWS/2), YUVHistogram::eYUV);
   //redHistogram.drawHistogram(imagePixmaps[HSV], (unsigned int)(IMAGE_COLS/2), (unsigned int)(IMAGE_ROWS/2), Histogram::eRED);
   //greenHistogram.drawHistogram(imagePixmaps[HSV], (unsigned int)(IMAGE_COLS/2), (unsigned int)(IMAGE_ROWS/2), Histogram::eGREEN);
   //blueHistogram.drawHistogram(imagePixmaps[HSV], (unsigned int)(IMAGE_COLS/2), (unsigned int)(IMAGE_ROWS/2), Histogram::eBLUE);
   //  display them in camera tab
   imageLabels[YUV]->setPixmap(imagePixmaps[YUV]);
   //imageLabels[RGB]->setPixmap(imagePixmaps[RGB]);
   //imageLabels[HSV]->setPixmap(imagePixmaps[HSV]); // USE HSV PIXMAP FOR TESTING - CHANGE LATER


   // Display entropy in message bar
   
/*******************************************************************************************************
   ostringstream est;
   est << "Your entropy is ";
   est << redHistogram.getEntropyValue();
   est << " + ";
   est << greenHistogram.getEntropyValue();
   est << " + ";
   est << blueHistogram.getEntropyValue();
   est << " = ";
   est << redHistogram.getEntropyValue()
          + greenHistogram.getEntropyValue()
          + blueHistogram.getEntropyValue();
   est << " That's a mess!";
   //est << RGBHistogram.getEntropyValue();
   emit showMessage(QString(est.str().c_str()));
*******************************************************************************************************/

   if (autoTuneOn) {
      tuneValue(yuvHistogram.getEntropyValue());
/*******************************************************************************************************
      tuneValue(redHistogram.getEntropyValue() +
                greenHistogram.getEntropyValue() +
                blueHistogram.getEntropyValue());
*******************************************************************************************************/
   }
}
コード例 #8
0
ファイル: gltext.cpp プロジェクト: hftom/MachinTruc
QImage* MyTextEffect::drawImage()
{
    QFont myFont;
    QPen myPen;
    myPen.setJoinStyle( Qt::RoundJoin );
    QBrush myBrush( QColor(0,0,0,0) );
    QColor backgroundColor(0,0,0,0);
    int outline = 0;
    int align = 1;

    int arrowType = 0, arrowSize = 0, arrowPos = 0;

    QStringList sl = currentText.split("\n");
    while ( !sl.isEmpty() ) {
        if ( sl.last().trimmed().isEmpty() )
            sl.takeLast();
        else
            break;
    }
    if ( sl.count() ) {
        QStringList desc = sl[0].split("|");
        if ( desc.count() >= 9 ) {
            myFont.fromString( desc[0] );
            myFont.setPointSize( desc[1].toInt() );
            myFont.setBold( desc[2].toInt() );
            myFont.setItalic( desc[3].toInt() );

            QStringList fc = desc[4].split( "." );
            if ( fc.count() == 2 ) {
                QColor col;
                col.setNamedColor( fc[ 0 ] );
                col.setAlpha( fc[ 1 ].toInt() );
                myPen.setColor( col );
                myBrush.setColor( col );
            }

            QStringList bc = desc[5].split( "." );
            if ( bc.count() == 2 ) {
                backgroundColor.setNamedColor( bc[ 0 ] );
                backgroundColor.setAlpha( bc[ 1 ].toInt() );
            }

            align = desc[6].toInt();

            int osize = desc[7].toInt();
            if ( osize > 0 ) {
                QStringList oc = desc[8].split( "." );
                if ( oc.count() == 2 ) {
                    outline = osize;
                    myPen.setWidth( osize );
                    myFont.setStyleStrategy( QFont::ForceOutline );
                    QColor col;
                    col.setNamedColor( oc[ 0 ] );
                    col.setAlpha( oc[ 1 ].toInt() );
                    myPen.setColor( col );
                }
            }
        }
        if ( desc.count() >= 12 ) {
            arrowType = desc[9].toInt();
            arrowSize = desc[10].toInt();
            arrowPos = desc[11].toInt();
        }
        sl.takeFirst();
    }

    QImage *image = new QImage( 10, 10, QImage::Format_ARGB32_Premultiplied );
    QPainter painter;
    painter.begin( image );
    painter.setPen( myPen );
    painter.setBrush( myBrush );
    painter.setFont( myFont );
    QList<QRectF> br;
    QFontMetrics metrics( myFont );
    int h = sl.count() * metrics.lineSpacing();
    int w = 0;
    for ( int i = 0; i < sl.count(); ++i ) {
        QRectF minrect( 0, 0, 1, 1 );
        QRectF r = painter.boundingRect( minrect, Qt::AlignHCenter | Qt::AlignVCenter, sl[i] );
        if ( r.width() > w )
            w = r.width();
        br.append( r );
    }
    QRectF minrect( 0, 0, 1, 1 );
    int margin = qMax( painter.boundingRect( minrect, Qt::AlignHCenter | Qt::AlignVCenter, "M" ).width() / 3.0, 3.0 );

    painter.end();

    double x = ((double)outline + margin * 2) / 2.0;
    double y = x;
    w += 2 * x;
    h += 2 * y;
    if ( w > iwidth ) {
        x -= (w - iwidth) / 2.0;
        w = iwidth;
    }
    if ( h > iheight ) {
        y -= (h - iheight) / 2.0;
        h = iheight;
    }

    QPointF polygon[7];
    arrowSize = h * arrowSize / 100.0;
    int n = 0;
    int leftOffset = 0, topOffset = 0;
    int wMargin = 0, hMargin = 0;
    if (arrowType) {
        switch (arrowType) {
        case 1: {
            leftOffset = arrowSize;
            wMargin = arrowSize;
            polygon[n].setX(1 + arrowSize);
            polygon[n++].setY(1);

            polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0 - arrowSize / 2.0) ) );
            polygon[n++].setX(1 + arrowSize);
            polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0) ) );
            polygon[n++].setX(1);
            polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0 + arrowSize / 2.0) ) );
            polygon[n++].setX(1 + arrowSize);

            polygon[n].setX(1 + arrowSize);
            polygon[n++].setY(h - 1);
            polygon[n].setX(w - 1 + arrowSize);
            polygon[n++].setY(h - 1);
            polygon[n].setX(w - 1 + arrowSize);
            polygon[n++].setY(1);
            break;
        }
        case 2: {
            wMargin = arrowSize;
            polygon[n].setX(1);
            polygon[n++].setY(1);
            polygon[n].setX(1);
            polygon[n++].setY(h - 1);
            polygon[n].setX(w - 1);
            polygon[n++].setY(h - 1);

            polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0 + arrowSize / 2.0) ) );
            polygon[n++].setX(w - 1);
            polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0) ) );
            polygon[n++].setX(w - 1 + arrowSize);
            polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0 - arrowSize / 2.0) ) );
            polygon[n++].setX(w - 1);

            polygon[n].setX(w - 1);
            polygon[n++].setY(1);
            break;
        }
        case 3: {
            topOffset = arrowSize;
            hMargin = arrowSize;
            polygon[n].setX(1);
            polygon[n++].setY(1 + arrowSize);
            polygon[n].setX(1);
            polygon[n++].setY(h - 1 + arrowSize);
            polygon[n].setX(w - 1);
            polygon[n++].setY(h - 1 + arrowSize);
            polygon[n].setX(w - 1);
            polygon[n++].setY(1 + arrowSize);

            polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0 + arrowSize / 2.0) ) );
            polygon[n++].setY(1 + arrowSize);
            polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0) ) );
            polygon[n++].setY(1);
            polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0 - arrowSize / 2.0) ) );
            polygon[n++].setY(1 + arrowSize);
            break;
        }
        case 4: {
            hMargin = arrowSize;
            polygon[n].setX(1);
            polygon[n++].setY(1);
            polygon[n].setX(1);
            polygon[n++].setY(h - 1);

            polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0 - arrowSize / 2.0) ) );
            polygon[n++].setY(h - 1);
            polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0) ) );
            polygon[n++].setY(h - 1 + arrowSize);
            polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0 + arrowSize / 2.0) ) );
            polygon[n++].setY(h - 1);

            polygon[n].setX(w - 1);
            polygon[n++].setY(h - 1);
            polygon[n].setX(w - 1);
            polygon[n++].setY(1);
            break;
        }
        }
    }

    delete image;
    image = new QImage( w + wMargin, h + hMargin, QImage::Format_ARGB32_Premultiplied );
    image->fill( QColor(0,0,0,0) );
    painter.begin( image );
    painter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing );
    if ( backgroundColor.alpha() > 0 ) {
        painter.setPen( QColor(0,0,0,0) );
        painter.setBrush( backgroundColor );
        if (arrowType) {
            painter.drawPolygon( polygon, 7 );
        }
        else {
            painter.drawRect( 1, 1, w - 2, h - 2 );
        }
    }
    painter.setPen( myPen );
    painter.setBrush( myBrush );
    painter.setFont( myFont );

    for ( int i = 0; i < sl.count(); ++i ) {
        QPointF point( 0, y + topOffset + metrics.ascent() );
        switch ( align ) {
        case 2: {
            point.setX( leftOffset + (double)w / 2.0 - br[i].width() / 2.0 );
            break;
        }
        case 3: {
            point.setX( leftOffset + w - x - br[i].width() );
            break;
        }
        default: {
            point.setX( leftOffset + x );
            break;
        }
        }
        if ( outline ) {
            QPainterPath myPath;
            myPath.addText( point, myFont, sl[i] );
            painter.drawPath( myPath );
        }
        else
            painter.drawText( point, sl[i] );
        y += metrics.lineSpacing();
    }
    painter.end();

    return image;
}
コード例 #9
0
void LibraryItemDelegate::paintCoverOnTrack(QPainter *painter, const QStyleOptionViewItem &opt, const QStandardItem *track) const
{
	Settings *settings = Settings::instance();
	const QImage *image = _libraryTreeView->expandedCover(static_cast<AlbumItem*>(track->parent()));
	if (image && !image->isNull()) {
		// Copy QStyleOptionViewItem to be able to expand it to the left, and take the maximum available space
		QStyleOptionViewItem option(opt);
		option.rect.setX(0);

		int totalHeight = track->model()->rowCount(track->parent()->index()) * option.rect.height();
		QImage scaled;
		QRect subRect;
		int row = _proxy->mapFromSource(track->index()).row();
		if (totalHeight > option.rect.width()) {
			scaled = image->scaledToWidth(option.rect.width());
			subRect = option.rect.translated(option.rect.width() - scaled.width(), -option.rect.y() + option.rect.height() * row);
		} else {
			scaled = image->scaledToHeight(totalHeight);
			int dx = option.rect.width() - scaled.width();
			subRect = option.rect.translated(-dx, -option.rect.y() + option.rect.height() * row);
		}

		// Fill with white when there are too much tracks to paint (height of all tracks is greater than the scaled image)
		QImage subImage = scaled.copy(subRect);
		if (scaled.height() < subRect.y() + subRect.height()) {
			subImage.fill(option.palette.base().color());
		}

		painter->save();
		painter->setOpacity(1 - settings->coverBelowTracksOpacity());
		painter->drawImage(option.rect, subImage);

		// Over paint black pixel in white
		QRect t(option.rect.x(), option.rect.y(), option.rect.width() - scaled.width(), option.rect.height());
		QImage white(t.size(), QImage::Format_ARGB32);
		white.fill(option.palette.base().color());
		painter->setOpacity(1.0);
		painter->drawImage(t, white);

		// Create a mix with 2 images: first one is a 3 pixels subimage of the album cover which is expanded to the left border
		// The second one is a computer generated gradient focused on alpha channel
		QImage leftBorder = scaled.copy(0, subRect.y(), 3, option.rect.height());
		if (!leftBorder.isNull()) {

			// Because the expanded border can look strange to one, is blurred with some gaussian function
			leftBorder = leftBorder.scaled(t.width(), option.rect.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
			leftBorder = ImageUtils::blurred(leftBorder, leftBorder.rect(), 10, false);
			painter->setOpacity(1 - settings->coverBelowTracksOpacity());
			painter->drawImage(t, leftBorder);

			QLinearGradient linearAlphaBrush(0, 0, leftBorder.width(), 0);
			linearAlphaBrush.setColorAt(0, QApplication::palette().base().color());
			linearAlphaBrush.setColorAt(1, Qt::transparent);

			painter->setOpacity(1.0);
			painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
			painter->setPen(Qt::NoPen);
			painter->setBrush(linearAlphaBrush);
			painter->drawRect(t);
		}
		painter->restore();
	}

	// Display a light selection rectangle when one is moving the cursor
	painter->save();
	QColor color = opt.palette.highlight().color();
	color.setAlphaF(0.66);
	if (opt.state.testFlag(QStyle::State_MouseOver) && !opt.state.testFlag(QStyle::State_Selected)) {
		painter->setPen(opt.palette.highlight().color());
		painter->setBrush(color.lighter(lighterValue));
		painter->drawRect(opt.rect.adjusted(0, 0, -1, -1));
	} else if (opt.state.testFlag(QStyle::State_Selected)) {
		// Display a not so light rectangle when one has chosen an item. It's darker than the mouse over
		painter->setPen(opt.palette.highlight().color());
		painter->setBrush(color.lighter(150));
		painter->drawRect(opt.rect.adjusted(0, 0, -1, -1));
	}
	painter->restore();
}
コード例 #10
0
ファイル: qgsmaprenderer.cpp プロジェクト: Aladar64/QGIS
void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
{
  //Lock render method for concurrent threads (e.g. from globe)
  QMutexLocker renderLock( &mRenderMutex );

  QgsDebugMsg( "========== Rendering ==========" );

  if ( mExtent.isEmpty() )
  {
    QgsDebugMsg( "empty extent... not rendering" );
    return;
  }

  if ( mSize.width() == 1 && mSize.height() == 1 )
  {
    QgsDebugMsg( "size 1x1... not rendering" );
    return;
  }

  QPaintDevice* thePaintDevice = painter->device();
  if ( !thePaintDevice )
  {
    return;
  }

  // wait
  if ( mDrawing )
  {
    QgsDebugMsg( "already rendering" );
    QCoreApplication::processEvents();
  }

  if ( mDrawing )
  {
    QgsDebugMsg( "still rendering - skipping" );
    return;
  }

  mDrawing = true;

  const QgsCoordinateTransform *ct;

#ifdef QGISDEBUG
  QgsDebugMsg( "Starting to render layer stack." );
  QTime renderTime;
  renderTime.start();
#endif

  if ( mOverview )
    mRenderContext.setDrawEditingInformation( !mOverview );

  mRenderContext.setPainter( painter );
  mRenderContext.setCoordinateTransform( 0 );
  //this flag is only for stopping during the current rendering progress,
  //so must be false at every new render operation
  mRenderContext.setRenderingStopped( false );

  // set selection color
  QgsProject* prj = QgsProject::instance();
  int myRed = prj->readNumEntry( "Gui", "/SelectionColorRedPart", 255 );
  int myGreen = prj->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 );
  int myBlue = prj->readNumEntry( "Gui", "/SelectionColorBluePart", 0 );
  int myAlpha = prj->readNumEntry( "Gui", "/SelectionColorAlphaPart", 255 );
  mRenderContext.setSelectionColor( QColor( myRed, myGreen, myBlue, myAlpha ) );

  //calculate scale factor
  //use the specified dpi and not those from the paint device
  //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene)
  double sceneDpi = mScaleCalculator->dpi();
  double scaleFactor = 1.0;
  if ( mOutputUnits == QgsMapRenderer::Millimeters )
  {
    if ( forceWidthScale )
    {
      scaleFactor = *forceWidthScale;
    }
    else
    {
      scaleFactor = sceneDpi / 25.4;
    }
  }
  double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi;
  if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor )
  {
    mRenderContext.setRasterScaleFactor( rasterScaleFactor );
  }
  if ( mRenderContext.scaleFactor() != scaleFactor )
  {
    mRenderContext.setScaleFactor( scaleFactor );
  }
  if ( mRenderContext.rendererScale() != mScale )
  {
    //add map scale to render context
    mRenderContext.setRendererScale( mScale );
  }
  if ( mLastExtent != mExtent )
  {
    mLastExtent = mExtent;
  }

  mRenderContext.setLabelingEngine( mLabelingEngine );
  if ( mLabelingEngine )
    mLabelingEngine->init( mapSettings() );

  // render all layers in the stack, starting at the base
  QListIterator<QString> li( mLayerSet );
  li.toBack();

  QgsRectangle r1, r2;

  while ( li.hasPrevious() )
  {
    if ( mRenderContext.renderingStopped() )
    {
      break;
    }

    // Store the painter in case we need to swap it out for the
    // cache painter
    QPainter * mypContextPainter = mRenderContext.painter();
    // Flattened image for drawing when a blending mode is set
    QImage * mypFlattenedImage = 0;

    QString layerId = li.previous();

    QgsDebugMsg( "Rendering at layer item " + layerId );

    // This call is supposed to cause the progress bar to
    // advance. However, it seems that updating the progress bar is
    // incompatible with having a QPainter active (the one that is
    // passed into this function), as Qt produces a number of errors
    // when try to do so. I'm (Gavin) not sure how to fix this, but
    // added these comments and debug statement to help others...
    QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" );

    //emit drawingProgress(myRenderCounter++, mLayerSet.size());
    QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );

    if ( !ml )
    {
      QgsDebugMsg( "Layer not found in registry!" );
      continue;
    }

    QgsDebugMsg( QString( "layer %1:  minscale:%2  maxscale:%3  scaledepvis:%4  extent:%5  blendmode:%6" )
                 .arg( ml->name() )
                 .arg( ml->minimumScale() )
                 .arg( ml->maximumScale() )
                 .arg( ml->hasScaleBasedVisibility() )
                 .arg( ml->extent().toString() )
                 .arg( ml->blendMode() )
               );

    if ( mRenderContext.useAdvancedEffects() )
    {
      // Set the QPainter composition mode so that this layer is rendered using
      // the desired blending mode
      mypContextPainter->setCompositionMode( ml->blendMode() );
    }

    if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mScale && mScale < ml->maximumScale() ) || mOverview )
    {
      connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );

      //
      // Now do the call to the layer that actually does
      // the rendering work!
      //

      bool split = false;

      if ( hasCrsTransformEnabled() )
      {
        r1 = mExtent;
        split = splitLayersExtent( ml, r1, r2 );
        ct = transformation( ml );
        mRenderContext.setExtent( r1 );
        QgsDebugMsg( "  extent 1: " + r1.toString() );
        QgsDebugMsg( "  extent 2: " + r2.toString() );
        if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer
        {
          continue;
        }
      }
      else
      {
        ct = NULL;
      }

      mRenderContext.setCoordinateTransform( ct );

      //decide if we have to scale the raster
      //this is necessary in case QGraphicsScene is used
      bool scaleRaster = false;
      QgsMapToPixel rasterMapToPixel;
      QgsMapToPixel bk_mapToPixel;

      if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 )
      {
        scaleRaster = true;
      }

      QSettings mySettings;

      // If we are drawing with an alternative blending mode then we need to render to a separate image
      // before compositing this on the map. This effectively flattens the layer and prevents
      // blending occuring between objects on the layer
      // (this is not required for raster layers or when layer caching is enabled, since that has the same effect)
      bool flattenedLayer = false;
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ((( vl->blendMode() != QPainter::CompositionMode_SourceOver )
             || ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
             || ( vl->layerTransparency() != 0 ) ) )
        {
          flattenedLayer = true;
          mypFlattenedImage = new QImage( mRenderContext.painter()->device()->width(),
                                          mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
          if ( mypFlattenedImage->isNull() )
          {
            QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) );
            emit drawError( ml );
            painter->end(); // drawError is not caught by anyone, so we end painting to notify caller
            return;
          }
          mypFlattenedImage->fill( 0 );
          QPainter * mypPainter = new QPainter( mypFlattenedImage );
          if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
          {
            mypPainter->setRenderHint( QPainter::Antialiasing );
          }
          mypPainter->scale( rasterScaleFactor,  rasterScaleFactor );
          mRenderContext.setPainter( mypPainter );
        }
      }

      // Per feature blending mode
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
        {
          // set the painter to the feature blend mode, so that features drawn
          // on this layer will interact and blend with each other
          mRenderContext.painter()->setCompositionMode( vl->featureBlendMode() );
        }
      }

      if ( scaleRaster )
      {
        bk_mapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor );
        rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor );
        mRenderContext.setMapToPixel( rasterMapToPixel );
        mRenderContext.painter()->save();
        mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
      }

      if ( !ml->draw( mRenderContext ) )
      {
        emit drawError( ml );
      }
      else
      {
        QgsDebugMsg( "Layer rendered without issues" );
      }

      if ( split )
      {
        mRenderContext.setExtent( r2 );
        if ( !ml->draw( mRenderContext ) )
        {
          emit drawError( ml );
        }
      }

      if ( scaleRaster )
      {
        mRenderContext.setMapToPixel( bk_mapToPixel );
        mRenderContext.painter()->restore();
      }

      //apply layer transparency for vector layers
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->layerTransparency() != 0 )
        {
          // a layer transparency has been set, so update the alpha for the flattened layer
          // by combining it with the layer transparency
          QColor transparentFillColor = QColor( 0, 0, 0, 255 - ( 255 * vl->layerTransparency() / 100 ) );
          // use destination in composition mode to merge source's alpha with destination
          mRenderContext.painter()->setCompositionMode( QPainter::CompositionMode_DestinationIn );
          mRenderContext.painter()->fillRect( 0, 0, mRenderContext.painter()->device()->width(),
                                              mRenderContext.painter()->device()->height(), transparentFillColor );
        }
      }

      if ( flattenedLayer )
      {
        // If we flattened this layer for alternate blend modes, composite it now
        delete mRenderContext.painter();
        mRenderContext.setPainter( mypContextPainter );
        mypContextPainter->save();
        mypContextPainter->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
        mypContextPainter->drawImage( 0, 0, *( mypFlattenedImage ) );
        mypContextPainter->restore();
        delete mypFlattenedImage;
        mypFlattenedImage = 0;
      }

      disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
    }
    else // layer not visible due to scale
    {
コード例 #11
0
ファイル: window.cpp プロジェクト: ongbe/xchart
void Window::init()
{
    m_data = new PrivateData;

    m_data->bar = new QScrollBar(Qt::Vertical, this);
    connect(m_data->bar,
            SIGNAL(valueChanged(int)),
            this,
            SLOT(update()));
    m_data->bar->setEnabled(true);
    m_data->bar->setRange(0, 32678 - 600);
    m_data->bar->setValue(0);
    m_data->bar->move(width() - 30, 0);
    m_data->bar->resize(30, height());




    m_data->renderer = new GraphLib::GraphAggRenderer();
    m_data->interactiveRenderer = new GraphLib::GraphAggInteractiveRenderer((GraphLib::GraphRenderer *)m_data->renderer);
    //
    //m_data->interactiveRenderer->setSize(NULL, 500, 500);
    //

    // 
    QImage *image = new QImage(10.00, 32.678, QImage::Format_ARGB32);
    image->fill(Qt::darkYellow);
    m_data->interactiveRenderer->setSize((void *)image, 
            image->width(), image->height());

    //m_data->renderer->beginRender();

    m_data->interactiveRenderer->fillPixelRect(200, 50, 30, 30, new QColor(Qt::red));

    GraphLib::Rectangle rect1(0, 0, 300, 300);
    m_data->interactiveRenderer->clipRegionAddRect(&rect1);


    resize(800, 600);

    m_data->renderer->beginRender();

    m_data->interactiveRenderer->fillPixelRect(200, 50, 30, 30, new QColor(Qt::red));

    m_data->renderer->setLineWidth(0.3);
    m_data->renderer->drawLine(new GraphLib::Point(10, 10), 
            new GraphLib::Point(30, 50), 
            new QColor(Qt::red));

    m_data->renderer->drawRect(new GraphLib::Point(50, 100), 
            new GraphLib::Point(150, 40201), new QColor(Qt::blue));

    m_data->renderer->fillRect(new GraphLib::Point(80, 50), 
            new GraphLib::Point(100, 70), new QColor(Qt::cyan));

    m_data->renderer->drawEllipse(new GraphLib::Point(50, 100), 
            20, 20, new QColor(0, 1, 0));

    m_data->renderer->fillEllipse(new GraphLib::Point(100, 100), 
            20, 20, new QColor(1, 1, 0));

    GraphLib::Point polyline[] = {QPoint(110, 210), QPoint(120,210), QPoint(130,220)};
    m_data->renderer->drawPolyline(polyline, 
            3, new QColor(1, 1, 0));

    GraphLib::Point polygon[] = {QPoint(110, 310), QPoint(120,310), QPoint(130,320)};
    m_data->renderer->drawPolygon(polygon, 
            3, new QColor(1, 1, 0));

    GraphLib::Point polygon1[] = {QPoint(110, 410), QPoint(120,410), QPoint(130,420)};
    m_data->renderer->fillPolygon(polygon1, 
            3, new QColor(1, 1, 0));

    //for (int i = 100; i < 99900; i+= 20) {
    for (int i = 100; i < 1000; i+= 20) {
        QString str = QString("line %1").arg(i);
        m_data->renderer->drawString(str, 
                new GraphLib::Point(20, i), 0, new QColor(1, 1, 0));
    }



    GraphLib::GraphAggRenderer *r = m_data->renderer;
    r->beginPath();
    r->moveTo(30, 30);
    r->lineTo(500, 500);

    r->moveTo(200, 200.2);
    r->lineTo(400, 200.2);

    r->moveTo(200, 100);
    r->lineTo(400, 100);


    r->moveTo(50.5, 50);
    r->lineTo(50.5, 200);
    r->setLineWidth(0.5);
    r->endPath();



    m_data->renderer->endRender();

}
コード例 #12
0
ファイル: textbutton.cpp プロジェクト: e1z0/openvpn_client
    QImage *createArrowBackground(const QMatrix &matrix) const
    {
        QRect scaledRect;
        scaledRect = matrix.mapRect(QRect(0, 0, this->logicalSize.width(), this->logicalSize.height()));

        QImage *image = new QImage(scaledRect.width(), scaledRect.height(), QImage::Format_ARGB32_Premultiplied);
        image->fill(QColor(0, 0, 0, 0).rgba());
        QPainter painter(image);
        painter.setRenderHint(QPainter::SmoothPixmapTransform);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(Qt::NoPen);

        if (Colors::useEightBitPalette){
            painter.setPen(QColor(120, 120, 120));
            if (this->pressed)
                painter.setBrush(QColor(60, 60, 60));
            else if (this->highlighted)
                painter.setBrush(QColor(100, 100, 100));
            else
                painter.setBrush(QColor(80, 80, 80));
        }
        else {
            QLinearGradient outlinebrush(0, 0, 0, scaledRect.height());
            QLinearGradient brush(0, 0, 0, scaledRect.height());

            brush.setSpread(QLinearGradient::PadSpread);
            QColor highlight(255, 255, 255, 70);
            QColor shadow(0, 0, 0, 70);
            QColor sunken(220, 220, 220, 30);
            QColor normal1 = QColor(200, 170, 160, 50);
            QColor normal2 = QColor(50, 10, 0, 50);

           if (pressed) {
               outlinebrush.setColorAt(0.0f, shadow);
               outlinebrush.setColorAt(1.0f, highlight);
               brush.setColorAt(0.0f, sunken);
               painter.setPen(Qt::NoPen);
           } else {
               outlinebrush.setColorAt(1.0f, shadow);
               outlinebrush.setColorAt(0.0f, highlight);
               brush.setColorAt(0.0f, normal1);
               if (!this->highlighted)
                   brush.setColorAt(1.0f, normal2);
               painter.setPen(QPen(outlinebrush, 1));
           }
           painter.setBrush(brush);
        }

        painter.drawRect(0, 0, scaledRect.width(), scaledRect.height());

        float xOff = scaledRect.width() / 2;
        float yOff = scaledRect.height() / 2;
        float sizex = 3.0f * matrix.m11();
        float sizey = 1.5f * matrix.m22();
        if (this->type == TextButton::UP)
            sizey *= -1;
        QPainterPath path;
        path.moveTo(xOff, yOff + (5 * sizey));
        path.lineTo(xOff - (4 * sizex), yOff - (3 * sizey));
        path.lineTo(xOff + (4 * sizex), yOff - (3 * sizey));
        path.lineTo(xOff, yOff + (5 * sizey));
        painter.drawPath(path);

        return image;
    }
コード例 #13
0
ファイル: scalebarobject.cpp プロジェクト: Elavina6/drishti
void
ScaleBarObject::draw(float pixelGLRatio,
		     int screenWidth, int screenHeight,
		     int viewWidth, int viewHeight,
		     bool grabsMouse)
{
  VolumeInformation pvlInfo = VolumeInformation::volumeInformation();

  QString str;
  bool horizontal = m_type;
  float slen = voxels();
  if (pvlInfo.voxelUnit > 0)
    {
      float avg = (pvlInfo.voxelSize[0] +
		   pvlInfo.voxelSize[1] +
		   pvlInfo.voxelSize[2])/3.0f;
      
      str = QString("%1 %2").			     \
	arg(slen, 0, 'f', Global::floatPrecision()).	\
	arg(pvlInfo.voxelUnitStringShort());     
      
      slen /= avg;
    }
  else
    str = QString("%1 voxels").arg(slen);

  slen = slen/pixelGLRatio;

  Vec s0 = Vec(m_pos.x()*viewWidth,
	       m_pos.y()*viewHeight,
	       1);
  
  Vec s1 = s0;
  if (horizontal)
    {
      slen *= (float)viewWidth/(float)screenWidth;
      s0 -= Vec(slen/2, 0, 0);
      s1 += Vec(slen/2, 0, 0);
    }
  else
    {
      slen *= (float)viewHeight/(float)screenHeight;
      s0 -= Vec(0, slen/2, 0);
      s1 += Vec(0, slen/2, 0);
    }
  
  glEnable(GL_BLEND);
  glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // back to front
  glColor4f(0, 0, 0, 0.8f);
  if (grabsMouse)
    {
      glColor4f(0.5f, 0, 0, 0.8f);
      glBegin(GL_QUADS);
      if (horizontal)
	{
	  glVertex2f(s0.x-5, s0.y-10);
	  glVertex2f(s1.x+5, s0.y-10);
	  glVertex2f(s1.x+5, s0.y+10);
	  glVertex2f(s0.x-5, s0.y+10);
	}
      else
	{
	  glVertex2f(s0.x-10, s0.y-5);
	  glVertex2f(s0.x-10, s1.y+5);
	  glVertex2f(s0.x+10, s1.y+5);
	  glVertex2f(s0.x+10, s0.y-5);
	}
      glEnd();
    }
  
  
  glDisable(GL_BLEND);
  glColor3f(1,1,1);
  glLineWidth(10);
  glBegin(GL_LINES);
  glVertex3fv(s0);
  glVertex3fv(s1);
  glEnd();
  
  glColor3f(0.5,0.5,0.5);
  glLineWidth(2);
  glBegin(GL_LINES);
  if (horizontal)
    {
      glVertex2f(s0.x+slen/2, s0.y-3);
      glVertex2f(s0.x+slen/2, s1.y+3);
    }
  else
    {
      glVertex2f(s1.x-3, (s1.y+s0.y)/2);
      glVertex2f(s0.x+3, (s1.y+s0.y)/2);
    }
  glEnd();
  glColor3f(0,0,0);
  glLineWidth(2);
  glBegin(GL_LINES);
  if (horizontal)
    {
      glVertex2f(s0.x+1, s0.y);
      glVertex2f(s1.x-1, s1.y);
    }
  else
    {
      glVertex2f(s0.x, s0.y+1);
      glVertex2f(s1.x, s1.y-1);
    }
  glEnd();
  glLineWidth(1);
  glColor3f(1,1,1);
  
  {
    Vec w0 = Vec(m_pos.x()*screenWidth, (1-m_pos.y())*screenHeight,1);
    Vec w1 = w0;
    if (horizontal)
      {
	w0 -= Vec(slen/2, 0, 0);
	w1 += Vec(slen/2, 0, 0);
      }
    else
      {
	w0 -= Vec(0, slen/2, 0);
	w1 += Vec(0, slen/2, 0);
      }
    
    QFont tfont = QFont("Helvetica", 12);
    tfont.setStyleStrategy(QFont::PreferAntialias);
    QFontMetrics metric(tfont);
    int mde = metric.descent();
    int fht = metric.height()+2;

    int fwd = metric.width(str)+2;
    QImage bImage = QImage(fwd, fht, QImage::Format_ARGB32);
    bImage.fill(0);
    QPainter bpainter(&bImage);
    Vec bgcolor = Global::backgroundColor();
    bpainter.setBackgroundMode(Qt::OpaqueMode);
    bpainter.setBackground(QColor(bgcolor.z*255,
				  bgcolor.y*255,
				  bgcolor.x*255));
    float bgintensity = (0.3*bgcolor.x +
			 0.5*bgcolor.y +
			 0.2*bgcolor.z);
    QColor penColor(Qt::white);
    if (bgintensity > 0.5) penColor = Qt::black;
    bpainter.setPen(penColor);
    bpainter.setFont(tfont);
    bpainter.drawText(1, fht-mde, str);
    
    QImage cImage = bImage.mirrored();
    if (!horizontal)
      {	    
	QMatrix matrix;
	matrix.rotate(90);
	cImage = cImage.transformed(matrix);
      }
    int x,y;
    if (horizontal)
      {
	x = (w0.x+w1.x)/2 - cImage.width()/2;
	y = w0.y-3-cImage.height();
	if (!m_textpos)
	  y = w0.y+6;
      }
    else
      {
	x = w1.x+3;
	if (!m_textpos)
	  x = w1.x-5-cImage.width();
	y = (w0.y+w1.y)/2 - cImage.height()/2;
      }
    glWindowPos2i(x,y);
    const uchar *bits = cImage.bits();
    glDrawPixels(cImage.width(), cImage.height(),
		 GL_RGBA,
		 GL_UNSIGNED_BYTE,
		 bits);
  }
}
コード例 #14
0
QImage * GroundPlaneGenerator::generateGroundPlaneAux(const QString & boardSvg, QSizeF boardImageSize, const QString & svg, QSizeF copperImageSize, 
													QStringList & exceptions, QGraphicsItem * board, double res, double & bWidth, double & bHeight) 
{
	QByteArray boardByteArray;
    QString tempColor("#ffffff");
    if (!SvgFileSplitter::changeColors(boardSvg, tempColor, exceptions, boardByteArray)) {
		return NULL;
	}

	
	//QFile file0("testGroundFillBoard.svg");
	//file0.open(QIODevice::WriteOnly);
	//QTextStream out0(&file0);
	//out0 << boardByteArray;
	//file0.close();
	
	QByteArray copperByteArray;
	if (!SvgFileSplitter::changeStrokeWidth(svg, m_strokeWidthIncrement, false, copperByteArray)) {
		return NULL;
	}
	
	//QFile file1("testGroundFillCopper.svg");
	//file1.open(QIODevice::WriteOnly);
	//QTextStream out1(&file1);
	//out1 << copperByteArray;
	//file1.close();
	

	double svgWidth = res * qMax(boardImageSize.width(), copperImageSize.width()) / FSvgRenderer::printerScale();
	double svgHeight = res * qMax(boardImageSize.height(), copperImageSize.height()) / FSvgRenderer::printerScale();

	QRectF br =  board->sceneBoundingRect();
	bWidth = res * br.width() / FSvgRenderer::printerScale();
	bHeight = res * br.height() / FSvgRenderer::printerScale();
	QImage * image = new QImage(qMax(svgWidth, bWidth), qMax(svgHeight, bHeight), QImage::Format_Mono); //
	image->setDotsPerMeterX(res * GraphicsUtils::InchesPerMeter);
	image->setDotsPerMeterY(res * GraphicsUtils::InchesPerMeter);
	image->fill(0x0);

	QSvgRenderer renderer(boardByteArray);
	QPainter painter;
	painter.begin(image);
	painter.setRenderHint(QPainter::Antialiasing, false);
	QRectF boardBounds(0, 0, res * boardImageSize.width() / FSvgRenderer::printerScale(), res * boardImageSize.height() / FSvgRenderer::printerScale()); 
	DebugDialog::debug("boardbounds", boardBounds);
	renderer.render(&painter, boardBounds);
	painter.end();

#ifndef QT_NO_DEBUG
	image->save("testGroundFillBoard.png");
#endif

	for (double m = 0; m < BORDERINCHES; m += (1.0 / res)) {   // 1 mm
		QList<QPoint> points;
		collectBorderPoints(*image, points);

#ifndef QT_NO_DEBUG
		/*
		// for debugging
		double pixelFactor = GraphicsUtils::StandardFritzingDPI / res;
		QPolygon polygon;
		foreach(QPoint p, points) {
			polygon.append(QPoint(p.x() * pixelFactor, p.y() * pixelFactor));
		}

		QList<QPolygon> polygons;
		polygons.append(polygon);
		QPointF offset;
		this
		QString pSvg = makePolySvg(polygons, res, bWidth, bHeight, pixelFactor, "#ffffff", false,  NULL, QSizeF(0,0), 0, QPointF(0, 0));
		*/
#endif

		foreach (QPoint p, points) image->setPixel(p, 0);
	}

#ifndef QT_NO_DEBUG
	image->save("testGroundFillBoardBorder.png");
#endif
	
	// "blur" the image a little

	QSvgRenderer renderer2(copperByteArray);
	painter.begin(image);
	painter.setRenderHint(QPainter::Antialiasing, false);
	QRectF bounds(0, 0, res * copperImageSize.width() / FSvgRenderer::printerScale(), res * copperImageSize.height() / FSvgRenderer::printerScale());
	DebugDialog::debug("copperbounds", bounds);
	renderer2.render(&painter, bounds);
	if (m_blurBy != 0) {
		bounds.moveTo(m_blurBy, 0);
		renderer2.render(&painter, bounds);
		bounds.moveTo(-m_blurBy, 0);
		renderer2.render(&painter, bounds);
		bounds.moveTo(0, m_blurBy);
		renderer2.render(&painter, bounds);
		bounds.moveTo(0, -m_blurBy);
		renderer2.render(&painter, bounds);
		bounds.moveTo(m_blurBy, m_blurBy);
		renderer2.render(&painter, bounds);
		bounds.moveTo(-m_blurBy, -m_blurBy);
		renderer2.render(&painter, bounds);
		bounds.moveTo(-m_blurBy, m_blurBy);
		renderer2.render(&painter, bounds);
		bounds.moveTo(m_blurBy, -m_blurBy);
		renderer2.render(&painter, bounds);
	}
	painter.end();

#ifndef QT_NO_DEBUG
	image->save("testGroundFillCopper.png");
#endif

	emit postImageSignal(this, image, board);	

	return image;
}