[composer] Fix image size/resolution was not honored during export (fix #13438)

This commit is contained in:
Nyall Dawson 2015-10-05 08:21:08 +11:00
parent 396ec2290b
commit e553a79256
6 changed files with 109 additions and 38 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 );
}

View File

@ -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

View File

@ -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 );

View File

@ -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