Skip to content

Commit e553a79

Browse files
committedOct 4, 2015
[composer] Fix image size/resolution was not honored during export (fix #13438)
1 parent 396ec22 commit e553a79

File tree

6 files changed

+109
-38
lines changed

6 files changed

+109
-38
lines changed
 

‎python/core/composer/qgscomposition.sip

+16-6
Original file line numberDiff line numberDiff line change
@@ -602,22 +602,32 @@ class QgsComposition : QGraphicsScene
602602
bool exportAsPDF( const QString& file );
603603

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

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

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

‎src/app/composer/qgscomposer.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -1948,7 +1948,7 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
19481948
// Image size
19491949
int width = ( int )( mComposition->printResolution() * mComposition->paperWidth() / 25.4 );
19501950
int height = ( int )( mComposition-> printResolution() * mComposition->paperHeight() / 25.4 );
1951-
int dpi = ( int )( mComposition->printResolution() );
1951+
int dpi = mComposition->printResolution();
19521952

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

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

22892291
QString imageFilename = filename;

‎src/app/composer/qgscomposerimageexportoptionsdialog.cpp

+22-6
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,16 @@ void QgsComposerImageExportOptionsDialog::setResolution( int resolution )
4545
{
4646
mWidthSpinBox->blockSignals( true );
4747
mHeightSpinBox->blockSignals( true );
48-
mWidthSpinBox->setValue( mImageSize.width() * resolution / 25.4 );
49-
mHeightSpinBox->setValue( mImageSize.height() * resolution / 25.4 );
48+
if ( mClipToContentGroupBox->isChecked() )
49+
{
50+
mWidthSpinBox->setValue( 0 );
51+
mHeightSpinBox->setValue( 0 );
52+
}
53+
else
54+
{
55+
mWidthSpinBox->setValue( mImageSize.width() * resolution / 25.4 );
56+
mHeightSpinBox->setValue( mImageSize.height() * resolution / 25.4 );
57+
}
5058
mWidthSpinBox->blockSignals( false );
5159
mHeightSpinBox->blockSignals( false );
5260
}
@@ -68,12 +76,12 @@ void QgsComposerImageExportOptionsDialog::setImageSize( const QSizeF& size )
6876
mHeightSpinBox->blockSignals( false );
6977
}
7078

71-
int QgsComposerImageExportOptionsDialog::width() const
79+
int QgsComposerImageExportOptionsDialog::imageWidth() const
7280
{
7381
return mWidthSpinBox->value();
7482
}
7583

76-
int QgsComposerImageExportOptionsDialog::height() const
84+
int QgsComposerImageExportOptionsDialog::imageHeight() const
7785
{
7886
return mHeightSpinBox->value();
7987
}
@@ -128,8 +136,16 @@ void QgsComposerImageExportOptionsDialog::on_mResolutionSpinBox_valueChanged( in
128136
{
129137
mWidthSpinBox->blockSignals( true );
130138
mHeightSpinBox->blockSignals( true );
131-
mWidthSpinBox->setValue( mImageSize.width() * value / 25.4 );
132-
mHeightSpinBox->setValue( mImageSize.height() * value / 25.4 );
139+
if ( mClipToContentGroupBox->isChecked() )
140+
{
141+
mWidthSpinBox->setValue( 0 );
142+
mHeightSpinBox->setValue( 0 );
143+
}
144+
else
145+
{
146+
mWidthSpinBox->setValue( mImageSize.width() * value / 25.4 );
147+
mHeightSpinBox->setValue( mImageSize.height() * value / 25.4 );
148+
}
133149
mWidthSpinBox->blockSignals( false );
134150
mHeightSpinBox->blockSignals( false );
135151
}

‎src/app/composer/qgscomposerimageexportoptionsdialog.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ class QgsComposerImageExportOptionsDialog: public QDialog, private Ui::QgsCompos
5959
void setImageSize( const QSizeF& size );
6060

6161
/** Returns the user-set image width in pixels.
62-
* @see height
62+
* @see imageHeight
6363
*/
64-
int width() const;
64+
int imageWidth() const;
6565

6666
/** Returns the user-set image height in pixels.
67-
* @see width
67+
* @see imageWidth
6868
*/
69-
int height() const;
69+
int imageHeight() const;
7070

7171
/** Sets whether the crop to contents option should be checked in the dialog
7272
* @param crop set to true to check crop to contents

‎src/core/composer/qgscomposition.cpp

+44-11
Original file line numberDiff line numberDiff line change
@@ -2887,16 +2887,32 @@ bool QgsComposition::print( QPrinter &printer, const bool evaluateDDPageSize )
28872887
return true;
28882888
}
28892889

2890-
QImage QgsComposition::printPageAsRaster( int page )
2890+
QImage QgsComposition::printPageAsRaster( int page, const QSize& imageSize, int dpi )
28912891
{
2892-
//print out via QImage, code copied from on_mActionExportAsImage_activated
2893-
int width = ( int )( printResolution() * paperWidth() / 25.4 );
2894-
int height = ( int )( printResolution() * paperHeight() / 25.4 );
2892+
int resolution = mPrintResolution;
2893+
if ( imageSize.isValid() )
2894+
{
2895+
//output size in pixels specified, calculate resolution using average of
2896+
//derived x/y dpi
2897+
resolution = ( imageSize.width() / mPageWidth
2898+
+ imageSize.height() / mPageHeight ) / 2.0 * 25.4;
2899+
}
2900+
else if ( dpi > 0 )
2901+
{
2902+
//dpi overridden by function parameters
2903+
resolution = dpi;
2904+
}
2905+
2906+
int width = imageSize.isValid() ? imageSize.width()
2907+
: ( int )( resolution * mPageWidth / 25.4 );
2908+
int height = imageSize.isValid() ? imageSize.height()
2909+
: ( int )( resolution * mPageHeight / 25.4 );
2910+
28952911
QImage image( QSize( width, height ), QImage::Format_ARGB32 );
28962912
if ( !image.isNull() )
28972913
{
2898-
image.setDotsPerMeterX( printResolution() / 25.4 * 1000 );
2899-
image.setDotsPerMeterY( printResolution() / 25.4 * 1000 );
2914+
image.setDotsPerMeterX( resolution / 25.4 * 1000 );
2915+
image.setDotsPerMeterY( resolution / 25.4 * 1000 );
29002916
image.fill( 0 );
29012917
QPainter imagePainter( &image );
29022918
renderPage( &imagePainter, page );
@@ -2905,15 +2921,32 @@ QImage QgsComposition::printPageAsRaster( int page )
29052921
return image;
29062922
}
29072923

2908-
QImage QgsComposition::renderRectAsRaster( const QRectF& rect )
2924+
QImage QgsComposition::renderRectAsRaster( const QRectF& rect, const QSize& imageSize, int dpi )
29092925
{
2910-
int width = ( int )( printResolution() * rect.width() / 25.4 );
2911-
int height = ( int )( printResolution() * rect.height() / 25.4 );
2926+
int resolution = mPrintResolution;
2927+
if ( imageSize.isValid() )
2928+
{
2929+
//output size in pixels specified, calculate resolution using average of
2930+
//derived x/y dpi
2931+
resolution = ( imageSize.width() / rect.width()
2932+
+ imageSize.height() / rect.height() ) / 2.0 * 25.4;
2933+
}
2934+
else if ( dpi > 0 )
2935+
{
2936+
//dpi overridden by function parameters
2937+
resolution = dpi;
2938+
}
2939+
2940+
int width = imageSize.isValid() ? imageSize.width()
2941+
: ( int )( resolution * rect.width() / 25.4 );
2942+
int height = imageSize.isValid() ? imageSize.height()
2943+
: ( int )( resolution * rect.height() / 25.4 );
2944+
29122945
QImage image( QSize( width, height ), QImage::Format_ARGB32 );
29132946
if ( !image.isNull() )
29142947
{
2915-
image.setDotsPerMeterX( printResolution() / 25.4 * 1000 );
2916-
image.setDotsPerMeterY( printResolution() / 25.4 * 1000 );
2948+
image.setDotsPerMeterX( resolution / 25.4 * 1000 );
2949+
image.setDotsPerMeterY( resolution / 25.4 * 1000 );
29172950
image.fill( Qt::transparent );
29182951
QPainter imagePainter( &image );
29192952
renderRect( &imagePainter, rect );

‎src/core/composer/qgscomposition.h

+16-6
Original file line numberDiff line numberDiff line change
@@ -665,22 +665,32 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
665665
bool exportAsPDF( const QString& file );
666666

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

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

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

1 commit comments

Comments
 (1)

agiudiceandrea commented on Feb 28, 2018

@agiudiceandrea
Member

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.