QgsRasterBlock* QgsSingleBandColorDataRenderer::block( int bandNo, QgsRectangle  const & extent, int width, int height )
{
  Q_UNUSED( bandNo );

  QgsRasterBlock *outputBlock = new QgsRasterBlock();
  if ( !mInput )
  {
    return outputBlock;
  }

  QgsRasterBlock *inputBlock = mInput->block( mBand, extent, width, height );
  if ( !inputBlock || inputBlock->isEmpty() )
  {
    QgsDebugMsg( "No raster data!" );
    delete inputBlock;
    return outputBlock;
  }

  bool hasTransparency = usesTransparency();
  if ( !hasTransparency )
  {
    // Nothing to do, just retype if necessary
    inputBlock->convert( QgsRasterBlock::ARGB32_Premultiplied );
    delete outputBlock;
    return inputBlock;
  }

  if ( !outputBlock->reset( QgsRasterBlock::ARGB32_Premultiplied, width, height ) )
  {
    delete inputBlock;
    return outputBlock;
  }

  for ( size_t i = 0; i < ( size_t )width*height; i++ )
  {
    QRgb pixelColor;
    double alpha = 255.0;
    QRgb c = inputBlock->color( i );
    alpha = qAlpha( c );
    pixelColor = qRgba( mOpacity * qRed( c ), mOpacity * qGreen( c ), mOpacity * qBlue( c ), mOpacity * alpha );
    outputBlock->setColor( i,  pixelColor );
  }

  delete inputBlock;
  return outputBlock;
}
예제 #2
0
QgsRasterBlock * QgsHueSaturationFilter::block( int bandNo, QgsRectangle  const & extent, int width, int height, QgsRasterBlockFeedback* feedback )
{
  Q_UNUSED( bandNo );
  QgsDebugMsgLevel( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ), 4 );

  QgsRasterBlock *outputBlock = new QgsRasterBlock();
  if ( !mInput )
  {
    return outputBlock;
  }

  // At this moment we know that we read rendered image
  int bandNumber = 1;
  QgsRasterBlock *inputBlock = mInput->block( bandNumber, extent, width, height, feedback );
  if ( !inputBlock || inputBlock->isEmpty() )
  {
    QgsDebugMsg( "No raster data!" );
    delete inputBlock;
    return outputBlock;
  }

  if ( mSaturation == 0 && mGrayscaleMode == GrayscaleOff && !mColorizeOn )
  {
    QgsDebugMsgLevel( "No hue/saturation change.", 4 );
    delete outputBlock;
    return inputBlock;
  }

  if ( !outputBlock->reset( Qgis::ARGB32_Premultiplied, width, height ) )
  {
    delete inputBlock;
    return outputBlock;
  }

  // adjust image
  QRgb myNoDataColor = qRgba( 0, 0, 0, 0 );
  QRgb myRgb;
  QColor myColor;
  int h, s, l;
  int r, g, b, alpha;
  double alphaFactor = 1.0;

  for ( qgssize i = 0; i < ( qgssize )width*height; i++ )
  {
    if ( inputBlock->color( i ) == myNoDataColor )
    {
      outputBlock->setColor( i, myNoDataColor );
      continue;
    }

    myRgb = inputBlock->color( i );
    myColor = QColor( myRgb );

    // Alpha must be taken from QRgb, since conversion from QRgb->QColor loses alpha
    alpha = qAlpha( myRgb );

    if ( alpha == 0 )
    {
      // totally transparent, no changes required
      outputBlock->setColor( i, myRgb );
      continue;
    }

    // Get rgb for color
    myColor.getRgb( &r, &g, &b );
    if ( alpha != 255 )
    {
      // Semi-transparent pixel. We need to adjust the colors since we are using Qgis::ARGB32_Premultiplied
      // and color values have been premultiplied by alpha
      alphaFactor = alpha / 255.;
      r /= alphaFactor;
      g /= alphaFactor;
      b /= alphaFactor;
      myColor = QColor::fromRgb( r, g, b );
    }

    myColor.getHsl( &h, &s, &l );

    // Changing saturation?
    if (( mGrayscaleMode != GrayscaleOff ) || ( mSaturationScale != 1 ) )
    {
      processSaturation( r, g, b, h, s, l );
    }

    // Colorizing?
    if ( mColorizeOn )
    {
      processColorization( r, g, b, h, s, l );
    }

    // Convert back to rgb
    if ( alpha != 255 )
    {
      // Transparent pixel, need to premultiply color components
      r *= alphaFactor;
      g *= alphaFactor;
      b *= alphaFactor;
    }

    outputBlock->setColor( i, qRgba( r, g, b, alpha ) );
  }

  delete inputBlock;
  return outputBlock;
}
예제 #3
0
QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRasterIterator* iter, int nCols, int nRows, const QgsRectangle& outputExtent,
    const QgsCoordinateReferenceSystem& crs, QProgressDialog* progressDialog )
{
  QgsDebugMsg( "Entered" );
  if ( !iter )
  {
    return SourceProviderError;
  }

  const QgsRasterInterface* iface = iter->input();
  QGis::DataType inputDataType = iface->dataType( 1 );
  if ( !iface || ( inputDataType != QGis::ARGB32 &&
                   inputDataType != QGis::ARGB32_Premultiplied ) )
  {
    return SourceProviderError;
  }

  iter->setMaximumTileWidth( mMaxTileWidth );
  iter->setMaximumTileHeight( mMaxTileHeight );

  void* redData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
  void* greenData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
  void* blueData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
  void* alphaData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
  QgsRectangle mapRect;
  int iterLeft = 0, iterTop = 0, iterCols = 0, iterRows = 0;
  int fileIndex = 0;

  //create destProvider for whole dataset here
  QgsRasterDataProvider* destProvider = 0;
  double pixelSize;
  double geoTransform[6];
  globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );

  destProvider = initOutput( nCols, nRows, crs, geoTransform, 4, QGis::Byte );

  iter->startRasterRead( 1, nCols, nRows, outputExtent );

  int nParts = 0;
  if ( progressDialog )
  {
    int nPartsX = nCols / iter->maximumTileWidth() + 1;
    int nPartsY = nRows / iter->maximumTileHeight() + 1;
    nParts = nPartsX * nPartsY;
    progressDialog->setMaximum( nParts );
    progressDialog->show();
    progressDialog->setLabelText( QObject::tr( "Reading raster part %1 of %2" ).arg( fileIndex + 1 ).arg( nParts ) );
  }

  QgsRasterBlock *inputBlock = 0;
  while ( iter->readNextRasterPart( 1, iterCols, iterRows, &inputBlock, iterLeft, iterTop ) )
  {
    if ( !inputBlock )
    {
      continue;
    }

    if ( progressDialog && fileIndex < ( nParts - 1 ) )
    {
      progressDialog->setValue( fileIndex + 1 );
      progressDialog->setLabelText( QObject::tr( "Reading raster part %1 of %2" ).arg( fileIndex + 2 ).arg( nParts ) );
      QCoreApplication::processEvents( QEventLoop::AllEvents, 1000 );
      if ( progressDialog->wasCanceled() )
      {
        delete inputBlock;
        break;
      }
    }

    //fill into red/green/blue/alpha channels
    qgssize nPixels = ( qgssize )iterCols * iterRows;
    // TODO: should be char not int? we are then copying 1 byte
    int red = 0;
    int green = 0;
    int blue = 0;
    int alpha = 255;
    for ( qgssize i = 0; i < nPixels; ++i )
    {
      QRgb c = inputBlock->color( i );
      alpha = qAlpha( c );
      red = qRed( c ); green = qGreen( c ); blue = qBlue( c );

      if ( inputDataType == QGis::ARGB32_Premultiplied )
      {
        double a = alpha / 255.;
        QgsDebugMsgLevel( QString( "red = %1 green = %2 blue = %3 alpha = %4 p = %5 a = %6" ).arg( red ).arg( green ).arg( blue ).arg( alpha ).arg(( int )c, 0, 16 ).arg( a ), 5 );
        red /= a;
        green /= a;
        blue /= a;
      }
      memcpy(( char* )redData + i, &red, 1 );
      memcpy(( char* )greenData + i, &green, 1 );
      memcpy(( char* )blueData + i, &blue, 1 );
      memcpy(( char* )alphaData + i, &alpha, 1 );
    }
    delete inputBlock;

    //create output file
    if ( mTiledMode )
    {
      //delete destProvider;
      QgsRasterDataProvider* partDestProvider = createPartProvider( outputExtent,
          nCols, iterCols, iterRows,
          iterLeft, iterTop, mOutputUrl, fileIndex,
          4, QGis::Byte, crs );

      if ( partDestProvider )
      {
        //write data to output file
        partDestProvider->write( redData, 1, iterCols, iterRows, 0, 0 );
        partDestProvider->write( greenData, 2, iterCols, iterRows, 0, 0 );
        partDestProvider->write( blueData, 3, iterCols, iterRows, 0, 0 );
        partDestProvider->write( alphaData, 4, iterCols, iterRows, 0, 0 );

        addToVRT( partFileName( fileIndex ), 1, iterCols, iterRows, iterLeft, iterTop );
        addToVRT( partFileName( fileIndex ), 2, iterCols, iterRows, iterLeft, iterTop );
        addToVRT( partFileName( fileIndex ), 3, iterCols, iterRows, iterLeft, iterTop );
        addToVRT( partFileName( fileIndex ), 4, iterCols, iterRows, iterLeft, iterTop );
        delete partDestProvider;
      }
    }
    else if ( destProvider )
    {
      destProvider->write( redData, 1, iterCols, iterRows, iterLeft, iterTop );
      destProvider->write( greenData, 2, iterCols, iterRows, iterLeft, iterTop );
      destProvider->write( blueData, 3, iterCols, iterRows, iterLeft, iterTop );
      destProvider->write( alphaData, 4, iterCols, iterRows, iterLeft, iterTop );
    }

    ++fileIndex;
  }

  if ( destProvider )
    delete destProvider;

  qgsFree( redData ); qgsFree( greenData ); qgsFree( blueData ); qgsFree( alphaData );

  if ( progressDialog )
  {
    progressDialog->setValue( progressDialog->maximum() );
  }

  if ( mTiledMode )
  {
    QString vrtFilePath( mOutputUrl + "/" + vrtFileName() );
    writeVRT( vrtFilePath );
    if ( mBuildPyramidsFlag == QgsRaster::PyramidsFlagYes )
    {
      buildPyramids( vrtFilePath );
    }
  }
  else
  {
    if ( mBuildPyramidsFlag == QgsRaster::PyramidsFlagYes )
    {
      buildPyramids( mOutputUrl );
    }
  }
  return NoError;
}
QgsRasterBlock * QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle  const & extent, int width, int height )
{
  Q_UNUSED( bandNo );
  QgsDebugMsg( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ) );

  QgsRasterBlock *outputBlock = new QgsRasterBlock();
  if ( !mInput )
  {
    return outputBlock;
  }

  // At this moment we know that we read rendered image
  int bandNumber = 1;
  QgsRasterBlock *inputBlock = mInput->block( bandNumber, extent, width, height );
  if ( !inputBlock || inputBlock->isEmpty() )
  {
    QgsDebugMsg( "No raster data!" );
    delete inputBlock;
    return outputBlock;
  }

  if ( mBrightness == 0 && mContrast == 0 )
  {
    QgsDebugMsg( "No brightness changes." );
    delete outputBlock;
    return inputBlock;
  }

  if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) )
  {
    delete inputBlock;
    return outputBlock;
  }

  // adjust image
  QRgb myNoDataColor = qRgba( 0, 0, 0, 0 );
  QRgb myColor;

  int r, g, b, alpha;
  double f = qPow(( mContrast + 100 ) / 100.0, 2 );

  for ( qgssize i = 0; i < ( qgssize )width*height; i++ )
  {
    if ( inputBlock->color( i ) == myNoDataColor )
    {
      outputBlock->setColor( i, myNoDataColor );
      continue;
    }

    myColor = inputBlock->color( i );
    alpha = qAlpha( myColor );

    r = adjustColorComponent( qRed( myColor ), alpha, mBrightness, f );
    g = adjustColorComponent( qGreen( myColor ), alpha, mBrightness, f );
    b = adjustColorComponent( qBlue( myColor ), alpha, mBrightness, f );

    outputBlock->setColor( i, qRgba( r, g, b, alpha ) );
  }

  delete inputBlock;
  return outputBlock;
}