Fix watermark size while scale sheet.
Add watermark placeholder for cases when raster image of watermark will require bigger size than image cache can handle.
This commit is contained in:
parent
4fe2e9688d
commit
2e9c94ffae
|
@ -114,7 +114,8 @@ void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem
|
||||||
if (watermarkData.showImage && not watermarkData.path.isEmpty())
|
if (watermarkData.showImage && not watermarkData.path.isEmpty())
|
||||||
{
|
{
|
||||||
VPTileFactory::PaintWatermarkImage(painter, img, watermarkData,
|
VPTileFactory::PaintWatermarkImage(painter, img, watermarkData,
|
||||||
layout->LayoutSettings().WatermarkPath());
|
layout->LayoutSettings().WatermarkPath(),
|
||||||
|
xScale, yScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watermarkData.showText && not watermarkData.text.isEmpty())
|
if (watermarkData.showText && not watermarkData.text.isEmpty())
|
||||||
|
|
|
@ -21,5 +21,7 @@
|
||||||
<file>puzzleicon/32X32/vertical_grainline.png</file>
|
<file>puzzleicon/32X32/vertical_grainline.png</file>
|
||||||
<file>puzzleicon/32X32/vertical_grainline@2x.png</file>
|
<file>puzzleicon/32X32/vertical_grainline@2x.png</file>
|
||||||
<file>puzzleicon/svg/no_watermark_image.svg</file>
|
<file>puzzleicon/svg/no_watermark_image.svg</file>
|
||||||
|
<file>puzzleicon/svg/watermark_placeholder.svg</file>
|
||||||
|
<file>puzzleicon/svg/watermark_placeholder_grayscale.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="100%" height="100%">
|
||||||
|
<rect id="sky" fill="#91BFF4" x="0" y="0" width="32" height="32"></rect>
|
||||||
|
<path id="mountain1" fill="#40915A" d="M26,32 L0,32 L0,26 L10,15 L26,32 Z"></path>
|
||||||
|
<path id="mountain2" fill="#4CAD6B" d="M32,20 L32,32 L4,32 L23,11 L32,20 Z"></path>
|
||||||
|
<rect id="sun" fill="#FFC90F" x="6" y="5" width="6" height="6" rx="3"></rect>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 471 B |
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="25.6pt" height="25.6pt" viewBox="0 0 25.6 25.6" version="1.1">
|
||||||
|
<g id="surface1">
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(72%,72%,72%);fill-opacity:1;" d="M 0 0 L 25.601562 0 L 25.601562 25.601562 L 0 25.601562 Z M 0 0 "/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(45%,45%,45%);fill-opacity:1;" d="M 20.800781 25.601562 L 0 25.601562 L 0 20.800781 L 8 12 Z M 20.800781 25.601562 "/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54%,54%,54%);fill-opacity:1;" d="M 25.601562 16 L 25.601562 25.601562 L 3.199219 25.601562 L 18.398438 8.800781 Z M 25.601562 16 "/>
|
||||||
|
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(77%,77%,77%);fill-opacity:1;" d="M 7.199219 4 C 8.53125 4 9.601562 5.070312 9.601562 6.398438 C 9.601562 7.730469 8.53125 8.800781 7.199219 8.800781 C 5.871094 8.800781 4.800781 7.730469 4.800781 6.398438 C 4.800781 5.070312 5.871094 4 7.199219 4 Z M 7.199219 4 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
|
@ -53,6 +53,7 @@ QT_WARNING_POP
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
#include <QLocalServer>
|
#include <QLocalServer>
|
||||||
#include <QFileOpenEvent>
|
#include <QFileOpenEvent>
|
||||||
|
#include <QPixmapCache>
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||||
|
@ -395,6 +396,8 @@ void VPApplication::InitOptions()
|
||||||
qCDebug(pApp, "Command-line arguments: %s", qUtf8Printable(arguments().join(", ")));
|
qCDebug(pApp, "Command-line arguments: %s", qUtf8Printable(arguments().join(", ")));
|
||||||
qCDebug(pApp, "Process ID: %s", qUtf8Printable(QString().setNum(applicationPid())));
|
qCDebug(pApp, "Process ID: %s", qUtf8Printable(QString().setNum(applicationPid())));
|
||||||
|
|
||||||
|
QPixmapCache::setCacheLimit(50 * 1024 /* 50 MB */);
|
||||||
|
|
||||||
LoadTranslation(QLocale().name());// By default the console version uses system locale
|
LoadTranslation(QLocale().name());// By default the console version uses system locale
|
||||||
|
|
||||||
VPCommandLine::Instance();
|
VPCommandLine::Instance();
|
||||||
|
|
|
@ -2827,16 +2827,12 @@ void VPMainWindow::DrawTilesScheme(QPrinter *printer, QPainter *painter, const V
|
||||||
if (watermarkData.showImage && not watermarkData.path.isEmpty())
|
if (watermarkData.showImage && not watermarkData.path.isEmpty())
|
||||||
{
|
{
|
||||||
VPTileFactory::PaintWatermarkImage(painter, target, watermarkData,
|
VPTileFactory::PaintWatermarkImage(painter, target, watermarkData,
|
||||||
m_layout->LayoutSettings().WatermarkPath(),
|
m_layout->LayoutSettings().WatermarkPath());
|
||||||
m_layout->LayoutSettings().HorizontalScale(),
|
|
||||||
m_layout->LayoutSettings().VerticalScale());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watermarkData.showText && not watermarkData.text.isEmpty())
|
if (watermarkData.showText && not watermarkData.text.isEmpty())
|
||||||
{
|
{
|
||||||
VPTileFactory::PaintWatermarkText(painter, target, watermarkData,
|
VPTileFactory::PaintWatermarkText(painter, target, watermarkData);
|
||||||
m_layout->LayoutSettings().HorizontalScale(),
|
|
||||||
m_layout->LayoutSettings().VerticalScale());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,10 @@ auto Grayscale(QImage image) -> QImage
|
||||||
auto WatermarkImageFromCache(const VWatermarkData &watermarkData, const QString &watermarkPath, qreal xScale,
|
auto WatermarkImageFromCache(const VWatermarkData &watermarkData, const QString &watermarkPath, qreal xScale,
|
||||||
qreal yScale, QString &error) -> QPixmap
|
qreal yScale, QString &error) -> QPixmap
|
||||||
{
|
{
|
||||||
const qreal opacity = watermarkData.opacity/100.;
|
|
||||||
QPixmap pixmap;
|
QPixmap pixmap;
|
||||||
QString imagePath = AbsoluteMPath(watermarkPath, watermarkData.path);
|
QString imagePath = AbsoluteMPath(watermarkPath, watermarkData.path);
|
||||||
QString imageCacheKey = QString("puzzle=path%1+opacity%2+rotation%3+grayscale%4+xscale%5+yxcale%6")
|
QString imageCacheKey = QString("puzzle=path%1+rotation%3+grayscale%4+xscale%5+yxcale%6")
|
||||||
.arg(imagePath, QString::number(opacity), QString::number(watermarkData.imageRotation),
|
.arg(imagePath, QString::number(watermarkData.imageRotation),
|
||||||
watermarkData.grayscale ? trueStr : falseStr ).arg(xScale).arg(yScale);
|
watermarkData.grayscale ? trueStr : falseStr ).arg(xScale).arg(yScale);
|
||||||
|
|
||||||
if (not QPixmapCache::find(imageCacheKey, &pixmap))
|
if (not QPixmapCache::find(imageCacheKey, &pixmap))
|
||||||
|
@ -57,26 +56,17 @@ auto WatermarkImageFromCache(const VWatermarkData &watermarkData, const QString
|
||||||
watermark = Grayscale(watermark);
|
watermark = Grayscale(watermark);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround for QGraphicsPixmapItem opacity problem.
|
|
||||||
// Opacity applied only if use a cached pixmap and only after first draw. First image always has opacity 1.
|
|
||||||
// Preparing an image manually allows to avoid the problem.
|
|
||||||
QSize scaledSize(qRound(watermark.width() * xScale), qRound(watermark.height() * yScale));
|
|
||||||
QImage tmp(scaledSize, watermark.format());
|
|
||||||
tmp = tmp.convertToFormat(QImage::Format_ARGB32);
|
|
||||||
tmp.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QPainter p(&tmp);
|
|
||||||
p.setOpacity(opacity);
|
|
||||||
|
|
||||||
QTransform t;
|
QTransform t;
|
||||||
t.translate(tmp.width()/2., tmp.height()/2.);
|
t.scale(1 / xScale, 1 / yScale);
|
||||||
|
watermark = watermark.transformed(t);
|
||||||
|
|
||||||
|
t = QTransform();
|
||||||
|
t.translate(watermark.width()/2., watermark.height()/2.);
|
||||||
t.rotate(-watermarkData.imageRotation);
|
t.rotate(-watermarkData.imageRotation);
|
||||||
t.translate(-tmp.width()/2., -tmp.height()/2.);
|
t.translate(-watermark.width()/2., -watermark.height()/2.);
|
||||||
p.setTransform(t);
|
watermark = watermark.transformed(t);
|
||||||
|
|
||||||
p.drawImage(QRectF(QPointF(), scaledSize), watermark);
|
pixmap = QPixmap::fromImage(watermark);
|
||||||
|
|
||||||
pixmap = QPixmap::fromImage(tmp);
|
|
||||||
|
|
||||||
QPixmapCache::insert(imageCacheKey, pixmap);
|
QPixmapCache::insert(imageCacheKey, pixmap);
|
||||||
}
|
}
|
||||||
|
@ -514,16 +504,12 @@ void VPTileFactory::DrawWatermark(QPainter *painter)
|
||||||
if (m_watermarkData.showImage && not m_watermarkData.path.isEmpty())
|
if (m_watermarkData.showImage && not m_watermarkData.path.isEmpty())
|
||||||
{
|
{
|
||||||
PaintWatermarkImage(painter, img, m_watermarkData,
|
PaintWatermarkImage(painter, img, m_watermarkData,
|
||||||
layout->LayoutSettings().WatermarkPath(),
|
layout->LayoutSettings().WatermarkPath());
|
||||||
layout->LayoutSettings().HorizontalScale(),
|
|
||||||
layout->LayoutSettings().VerticalScale());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_watermarkData.showText && not m_watermarkData.text.isEmpty())
|
if (m_watermarkData.showText && not m_watermarkData.text.isEmpty())
|
||||||
{
|
{
|
||||||
PaintWatermarkText(painter, img, m_watermarkData,
|
PaintWatermarkText(painter, img, m_watermarkData);
|
||||||
layout->LayoutSettings().HorizontalScale(),
|
|
||||||
layout->LayoutSettings().VerticalScale());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,9 +561,9 @@ void VPTileFactory::PaintWatermarkImage(QPainter *painter, const QRectF &img, co
|
||||||
{
|
{
|
||||||
SCASSERT(painter != nullptr)
|
SCASSERT(painter != nullptr)
|
||||||
|
|
||||||
auto BrokenImage = [img, watermarkData, watermarkPath]()
|
|
||||||
{
|
|
||||||
const qreal opacity = watermarkData.opacity/100.;
|
const qreal opacity = watermarkData.opacity/100.;
|
||||||
|
auto BrokenImage = [img, watermarkData, watermarkPath, opacity]()
|
||||||
|
{
|
||||||
QPixmap watermark;
|
QPixmap watermark;
|
||||||
QString imagePath = QString("puzzle=path%1+opacity%2_broken")
|
QString imagePath = QString("puzzle=path%1+opacity%2_broken")
|
||||||
.arg(AbsoluteMPath(watermarkPath, watermarkData.path), QString::number(opacity));
|
.arg(AbsoluteMPath(watermarkPath, watermarkData.path), QString::number(opacity));
|
||||||
|
@ -604,8 +590,57 @@ void VPTileFactory::PaintWatermarkImage(QPainter *painter, const QRectF &img, co
|
||||||
return watermark;
|
return watermark;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QString imagePath = AbsoluteMPath(watermarkPath, watermarkData.path);
|
||||||
|
QFileInfo f(imagePath);
|
||||||
|
|
||||||
|
QImageReader imageReader(imagePath);
|
||||||
|
QImage watermarkImage = imageReader.read();
|
||||||
|
|
||||||
|
if (watermarkImage.isNull())
|
||||||
|
{
|
||||||
|
QPixmap watermarkPixmap = BrokenImage();
|
||||||
|
|
||||||
|
if (watermarkPixmap.width() < img.width() && watermarkPixmap.height() < img.height())
|
||||||
|
{
|
||||||
|
QRect imagePosition(0, 0, watermarkPixmap.width(), watermarkPixmap.height());
|
||||||
|
imagePosition.translate(img.center().toPoint() - imagePosition.center());
|
||||||
|
|
||||||
|
painter->drawPixmap(imagePosition, watermarkPixmap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
painter->drawPixmap(img.toRect(), watermarkPixmap);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||||
|
qint64 fileSize = watermarkImage.byteCount();
|
||||||
|
#else
|
||||||
|
qint64 fileSize = watermarkImage.sizeInBytes();
|
||||||
|
#endif
|
||||||
|
qint64 pixelSize = fileSize / watermarkImage.height() / watermarkImage.width();
|
||||||
|
QSize scaledSize(qRound(watermarkImage.width() / xScale), qRound(watermarkImage.height() / yScale));
|
||||||
|
qint64 scaledImageSize = pixelSize*scaledSize.width()*scaledSize.height() / 1024;
|
||||||
|
int limit = QPixmapCache::cacheLimit();
|
||||||
|
|
||||||
|
if (scaledImageSize > limit && (xScale < 1 || yScale < 1))
|
||||||
|
{
|
||||||
|
QScopedPointer<QSvgRenderer> svgRenderer(new QSvgRenderer());
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->setOpacity(opacity);
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
|
QString grayscale = watermarkData.grayscale ? QStringLiteral("_grayscale") : QString();
|
||||||
|
svgRenderer->load(QStringLiteral("://puzzleicon/svg/watermark_placeholder%1.svg").arg(grayscale));
|
||||||
|
QRect imageRect(0, 0, qRound(watermarkImage.width() / xScale), qRound(watermarkImage.height() / yScale));
|
||||||
|
imageRect.translate(img.center().toPoint() - imageRect.center());
|
||||||
|
svgRenderer->render(painter, imageRect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QPixmap watermark;
|
QPixmap watermark;
|
||||||
QFileInfo f(watermarkData.path);
|
|
||||||
if (f.suffix() == "png" || f.suffix() == "jpg" || f.suffix() == "jpeg" || f.suffix() == "bmp")
|
if (f.suffix() == "png" || f.suffix() == "jpg" || f.suffix() == "jpeg" || f.suffix() == "bmp")
|
||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
|
@ -621,6 +656,9 @@ void VPTileFactory::PaintWatermarkImage(QPainter *painter, const QRectF &img, co
|
||||||
watermark = BrokenImage();
|
watermark = BrokenImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->setOpacity(watermarkData.opacity/100.);
|
||||||
|
|
||||||
if (watermark.width() < img.width() && watermark.height() < img.height())
|
if (watermark.width() < img.width() && watermark.height() < img.height())
|
||||||
{
|
{
|
||||||
QRect imagePosition(0, 0, watermark.width(), watermark.height());
|
QRect imagePosition(0, 0, watermark.width(), watermark.height());
|
||||||
|
@ -632,4 +670,6 @@ void VPTileFactory::PaintWatermarkImage(QPainter *painter, const QRectF &img, co
|
||||||
{
|
{
|
||||||
painter->drawPixmap(img.toRect(), watermark);
|
painter->drawPixmap(img.toRect(), watermark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user