Skip to content
Permalink
Browse files
[composer] Fix image size/resolution was not honored during export (fix
  • Loading branch information
nyalldawson committed Oct 4, 2015
1 parent 396ec22 commit e553a792561da4a1d5d30040808343e5337eec0b
@@ -602,22 +602,32 @@ class QgsComposition : QGraphicsScene
bool exportAsPDF( const QString& file );

/** Renders a composer page to an image.
* @param page page number, 0 based such that the first page is page 0
* @returns rendered image, or null image if image does not fit into available memory
* @see renderRectAsRaster()
* @see renderPage()
* @param page page number, 0 based such that the first page is page 0
* @param imageSize optional target image size, in pixels. It is the caller's responsibility
* to ensure that the ratio of the target image size matches the ratio of the composition
* page size.
* @param dpi optional dpi override, or 0 to use default composition print resolution. This
* parameter has no effect if imageSize is specified.
* @returns rendered image, or null image if image does not fit into available memory
* @see renderRectAsRaster()
* @see renderPage()
*/
QImage printPageAsRaster( int page );
QImage printPageAsRaster( int page, const QSize& imageSize = QSize(), int dpi = 0 );

/** Renders a portion of the composition to an image. This method can be used to render
* sections of pages rather than full pages.
* @param rect region of composition to render
* @param imageSize optional target image size, in pixels. It is the caller's responsibility
* to ensure that the ratio of the target image size matches the ratio of the specified
* region of the composition.
* @param dpi optional dpi override, or 0 to use default composition print resolution. This
* parameter has no effect if imageSize is specified.
* @returns rendered image, or null image if image does not fit into available memory
* @note added in QGIS 2.12
* @see printPageAsRaster()
* @see renderRect()
*/
QImage renderRectAsRaster( const QRectF& rect );
QImage renderRectAsRaster( const QRectF& rect, const QSize& imageSize = QSize(), int dpi = 0 );

/** Renders a full page to a paint device.
* @param p destination painter
@@ -1948,7 +1948,7 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
// Image size
int width = ( int )( mComposition->printResolution() * mComposition->paperWidth() / 25.4 );
int height = ( int )( mComposition-> printResolution() * mComposition->paperHeight() / 25.4 );
int dpi = ( int )( mComposition->printResolution() );
int dpi = mComposition->printResolution();

int memuse = width * height * 3 / 1000000; // pixmap + image
QgsDebugMsg( QString( "Image %1x%2" ).arg( width ).arg( height ) );
@@ -2047,11 +2047,11 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
-marginTop * pixelToMm,
marginRight * pixelToMm,
marginBottom * pixelToMm );
image = mComposition->renderRectAsRaster( bounds );
image = mComposition->renderRectAsRaster( bounds, QSize(), imageDlg.resolution() );
}
else
{
image = mComposition->printPageAsRaster( i );
image = mComposition->printPageAsRaster( i, QSize( imageDlg.imageWidth(), imageDlg.imageHeight() ) );
}

if ( image.isNull() )
@@ -2279,11 +2279,13 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
-marginTop * pixelToMm,
marginRight * pixelToMm,
marginBottom * pixelToMm );
image = mComposition->renderRectAsRaster( bounds );
image = mComposition->renderRectAsRaster( bounds, QSize(), imageDlg.resolution() );
}
else
{
image = mComposition->printPageAsRaster( i );
//note - we can't safely use the preset width/height set in imageDlg here,
//as the atlas may have differing page size. So use resolution instead.
image = mComposition->printPageAsRaster( i, QSize(), imageDlg.resolution() );
}

QString imageFilename = filename;
@@ -45,8 +45,16 @@ void QgsComposerImageExportOptionsDialog::setResolution( int resolution )
{
mWidthSpinBox->blockSignals( true );
mHeightSpinBox->blockSignals( true );
mWidthSpinBox->setValue( mImageSize.width() * resolution / 25.4 );
mHeightSpinBox->setValue( mImageSize.height() * resolution / 25.4 );
if ( mClipToContentGroupBox->isChecked() )
{
mWidthSpinBox->setValue( 0 );
mHeightSpinBox->setValue( 0 );
}
else
{
mWidthSpinBox->setValue( mImageSize.width() * resolution / 25.4 );
mHeightSpinBox->setValue( mImageSize.height() * resolution / 25.4 );
}
mWidthSpinBox->blockSignals( false );
mHeightSpinBox->blockSignals( false );
}
@@ -68,12 +76,12 @@ void QgsComposerImageExportOptionsDialog::setImageSize( const QSizeF& size )
mHeightSpinBox->blockSignals( false );
}

int QgsComposerImageExportOptionsDialog::width() const
int QgsComposerImageExportOptionsDialog::imageWidth() const
{
return mWidthSpinBox->value();
}

int QgsComposerImageExportOptionsDialog::height() const
int QgsComposerImageExportOptionsDialog::imageHeight() const
{
return mHeightSpinBox->value();
}
@@ -128,8 +136,16 @@ void QgsComposerImageExportOptionsDialog::on_mResolutionSpinBox_valueChanged( in
{
mWidthSpinBox->blockSignals( true );
mHeightSpinBox->blockSignals( true );
mWidthSpinBox->setValue( mImageSize.width() * value / 25.4 );
mHeightSpinBox->setValue( mImageSize.height() * value / 25.4 );
if ( mClipToContentGroupBox->isChecked() )
{
mWidthSpinBox->setValue( 0 );
mHeightSpinBox->setValue( 0 );
}
else
{
mWidthSpinBox->setValue( mImageSize.width() * value / 25.4 );
mHeightSpinBox->setValue( mImageSize.height() * value / 25.4 );
}
mWidthSpinBox->blockSignals( false );
mHeightSpinBox->blockSignals( false );
}
@@ -59,14 +59,14 @@ class QgsComposerImageExportOptionsDialog: public QDialog, private Ui::QgsCompos
void setImageSize( const QSizeF& size );

/** Returns the user-set image width in pixels.
* @see height
* @see imageHeight
*/
int width() const;
int imageWidth() const;

/** Returns the user-set image height in pixels.
* @see width
* @see imageWidth
*/
int height() const;
int imageHeight() const;

/** Sets whether the crop to contents option should be checked in the dialog
* @param crop set to true to check crop to contents
@@ -2887,16 +2887,32 @@ bool QgsComposition::print( QPrinter &printer, const bool evaluateDDPageSize )
return true;
}

QImage QgsComposition::printPageAsRaster( int page )
QImage QgsComposition::printPageAsRaster( int page, const QSize& imageSize, int dpi )
{
//print out via QImage, code copied from on_mActionExportAsImage_activated
int width = ( int )( printResolution() * paperWidth() / 25.4 );
int height = ( int )( printResolution() * paperHeight() / 25.4 );
int resolution = mPrintResolution;
if ( imageSize.isValid() )
{
//output size in pixels specified, calculate resolution using average of
//derived x/y dpi
resolution = ( imageSize.width() / mPageWidth
+ imageSize.height() / mPageHeight ) / 2.0 * 25.4;
}
else if ( dpi > 0 )
{
//dpi overridden by function parameters
resolution = dpi;
}

int width = imageSize.isValid() ? imageSize.width()
: ( int )( resolution * mPageWidth / 25.4 );
int height = imageSize.isValid() ? imageSize.height()
: ( int )( resolution * mPageHeight / 25.4 );

QImage image( QSize( width, height ), QImage::Format_ARGB32 );
if ( !image.isNull() )
{
image.setDotsPerMeterX( printResolution() / 25.4 * 1000 );
image.setDotsPerMeterY( printResolution() / 25.4 * 1000 );
image.setDotsPerMeterX( resolution / 25.4 * 1000 );
image.setDotsPerMeterY( resolution / 25.4 * 1000 );
image.fill( 0 );
QPainter imagePainter( &image );
renderPage( &imagePainter, page );
@@ -2905,15 +2921,32 @@ QImage QgsComposition::printPageAsRaster( int page )
return image;
}

QImage QgsComposition::renderRectAsRaster( const QRectF& rect )
QImage QgsComposition::renderRectAsRaster( const QRectF& rect, const QSize& imageSize, int dpi )
{
int width = ( int )( printResolution() * rect.width() / 25.4 );
int height = ( int )( printResolution() * rect.height() / 25.4 );
int resolution = mPrintResolution;
if ( imageSize.isValid() )
{
//output size in pixels specified, calculate resolution using average of
//derived x/y dpi
resolution = ( imageSize.width() / rect.width()
+ imageSize.height() / rect.height() ) / 2.0 * 25.4;
}
else if ( dpi > 0 )
{
//dpi overridden by function parameters
resolution = dpi;
}

int width = imageSize.isValid() ? imageSize.width()
: ( int )( resolution * rect.width() / 25.4 );
int height = imageSize.isValid() ? imageSize.height()
: ( int )( resolution * rect.height() / 25.4 );

QImage image( QSize( width, height ), QImage::Format_ARGB32 );
if ( !image.isNull() )
{
image.setDotsPerMeterX( printResolution() / 25.4 * 1000 );
image.setDotsPerMeterY( printResolution() / 25.4 * 1000 );
image.setDotsPerMeterX( resolution / 25.4 * 1000 );
image.setDotsPerMeterY( resolution / 25.4 * 1000 );
image.fill( Qt::transparent );
QPainter imagePainter( &image );
renderRect( &imagePainter, rect );
@@ -665,22 +665,32 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
bool exportAsPDF( const QString& file );

/** Renders a composer page to an image.
* @param page page number, 0 based such that the first page is page 0
* @returns rendered image, or null image if image does not fit into available memory
* @see renderRectAsRaster()
* @see renderPage()
* @param page page number, 0 based such that the first page is page 0
* @param imageSize optional target image size, in pixels. It is the caller's responsibility
* to ensure that the ratio of the target image size matches the ratio of the composition
* page size.
* @param dpi optional dpi override, or 0 to use default composition print resolution. This
* parameter has no effect if imageSize is specified.
* @returns rendered image, or null image if image does not fit into available memory
* @see renderRectAsRaster()
* @see renderPage()
*/
QImage printPageAsRaster( int page );
QImage printPageAsRaster( int page, const QSize& imageSize = QSize(), int dpi = 0 );

/** Renders a portion of the composition to an image. This method can be used to render
* sections of pages rather than full pages.
* @param rect region of composition to render
* @param imageSize optional target image size, in pixels. It is the caller's responsibility
* to ensure that the ratio of the target image size matches the ratio of the specified
* region of the composition.
* @param dpi optional dpi override, or 0 to use default composition print resolution. This
* parameter has no effect if imageSize is specified.
* @returns rendered image, or null image if image does not fit into available memory
* @note added in QGIS 2.12
* @see printPageAsRaster()
* @see renderRect()
*/
QImage renderRectAsRaster( const QRectF& rect );
QImage renderRectAsRaster( const QRectF& rect, const QSize& imageSize = QSize(), int dpi = 0 );

/** Renders a full page to a paint device.
* @param p destination painter

1 comment on commit e553a79

@agiudiceandrea

This comment has been minimized.

Copy link
Contributor

@agiudiceandrea agiudiceandrea commented on e553a79 Feb 28, 2018

Hi @nyalldawson,
it seems to me that this commit introduced a problem when exporting images as raster. Could you please take a look at the bug report 18132?

Please sign in to comment.