Commit a4b8caca authored by Halla Rempt's avatar Halla Rempt

Scale the qpainter canvas with a lanczos filter

Needs to be made optional.
parent 23383775
......@@ -18,6 +18,7 @@ configure_file(config-processor.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-proce
include(kdefx.cmake)
set(kritaui_LIB_SRCS
canvas/scalefilter.cpp
canvas/kis_canvas_widget_base.cpp
canvas/kis_canvas2.cpp
canvas/kis_canvas_controller.cpp
......
......@@ -20,7 +20,7 @@
#include <QPainter>
#include "kis_debug.h"
#include "scalefilter.h"
#include <math.h>
/****** Some helper functions *******/
......@@ -51,6 +51,7 @@ inline void scaleRect(QRect &rc, qreal scaleX, qreal scaleY)
rc.setRect(x, y, w, h);
}
/*********** KisImagePatch ************/
KisImagePatch::KisImagePatch()
......@@ -102,8 +103,8 @@ void KisImagePatch::preScale(const QRectF &dstRect)
m_scaleY *= scaleY;
scaleRect(m_interestRect, scaleX, scaleY);
m_image = m_image.scaled(newImageSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
//m_image = Blitz::smoothScaleFilter(m_image, newImageSize, 1.0, Blitz::LanczosFilter);
m_isScaled = true;
......@@ -120,12 +121,10 @@ bool KisImagePatch::isValid()
}
void KisImagePatch::drawMe(QPainter &gc,
const QRectF &dstRect,
QPainter::RenderHints renderHints)
const QRectF &dstRect)
{
gc.save();
gc.setCompositionMode(QPainter::CompositionMode_Source);
gc.setRenderHints(renderHints, true);
gc.drawImage(dstRect, m_image, m_interestRect);
gc.restore();
......
......@@ -72,8 +72,7 @@ public:
* @renderHints are directly tranmitted to QPainter
*/
void drawMe(QPainter &gc,
const QRectF &dstRect,
QPainter::RenderHints renderHints);
const QRectF &dstRect);
/**
* Checks whether the patch can be used for drawing the image
......
......@@ -30,6 +30,7 @@
#include "kis_config_notifier.h"
#include "kis_debug.h"
#include "kis_config.h"
#include "scalefilter.h"
//#define DEBUG_PYRAMID
......@@ -170,6 +171,28 @@ void KisImagePyramid::setImage(KisImageWSP newImage)
if (newImage) {
m_originalImage = newImage;
// KisPaintDeviceSP dev = newImage->projection();
// QImage img = dev->convertToQImage(0);
// QSize sz = img.size() / 4;
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::BesselFilter).save("bessel.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::BlackmanFilter).save("blackman.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::BoxFilter).save("box.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::CatromFilter).save("catrom.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::CubicFilter).save("cubic.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::GaussianFilter).save("gaussian.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::HammingFilter).save("hamming.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::HanningFilter).save("hanning.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::HermiteFilter).save("hermite.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::LanczosFilter).save("lanczos.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::MitchellFilter).save("mitchell.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::PointFilter).save("point.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::QuadraticFilter).save("quadratic.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::SincFilter).save("sinc.png");
// Blitz::smoothScaleFilter(img, sz, 1.0, Blitz::TriangleFilter).save("triangle.png");
// img.scaled(sz, Qt::IgnoreAspectRatio, Qt::FastTransformation).save("fast.png");
// img.scaled(sz, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).save("smooth.png");
clearPyramid();
setImageSize(m_originalImage->width(), m_originalImage->height());
retrieveImageData(m_originalImage->projection()->exactBounds());
......@@ -462,7 +485,7 @@ KisImagePatch KisImagePyramid::getNearestPatch(KisPPUpdateInfoSP info)
void KisImagePyramid::drawFromOriginalImage(QPainter& gc, KisPPUpdateInfoSP info)
{
KisImagePatch patch = getNearestPatch(info);
patch.drawMe(gc, info->viewportRect, info->renderHints);
patch.drawMe(gc, info->viewportRect);
}
QImage KisImagePyramid::convertToQImageFast(KisPaintDeviceSP paintDevice,
......
......@@ -370,19 +370,17 @@ void KisPrescaledProjection::fillInUpdateInformation(const QRect &viewportRect,
if (SCALE_MORE_OR_EQUAL_TO(info->scaleX, info->scaleY, 1.0)) {
if (SCALE_LESS_THAN(info->scaleX, info->scaleY, 2.0)) {
dbgRender << "smoothBetween100And200Percent" << endl;
info->renderHints = QPainter::SmoothPixmapTransform;
info->borderWidth = borderSize;
}
info->transfer = KisPPUpdateInfo::DIRECT;
} else { // <100%
info->renderHints = QPainter::SmoothPixmapTransform;
info->borderWidth = borderSize;
info->transfer = KisPPUpdateInfo::PATCH;
}
dbgRender << "#####################################";
dbgRender << ppVar(info->scaleX) << ppVar(info->scaleY);
dbgRender << ppVar(info->borderWidth) << ppVar(info->renderHints);
dbgRender << ppVar(info->borderWidth);
dbgRender << ppVar(info->transfer);
dbgRender << ppVar(info->dirtyImageRect);
dbgRender << "Not aligned rect of the canvas (raw):\t" << croppedViewRect;
......@@ -409,7 +407,7 @@ void KisPrescaledProjection::drawUsingBackend(QPainter &gc, KisPPUpdateInfoSP in
// prescale the patch because otherwise we'd scale using QPainter, which gives
// a crap result compared to QImage's smoothscale
patch.preScale(info->viewportRect);
patch.drawMe(gc, info->viewportRect, info->renderHints);
patch.drawMe(gc, info->viewportRect);
}
}
......
......@@ -116,7 +116,6 @@ void KisQPainterCanvas::paintEvent(QPaintEvent * ev)
m_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
}
QPainter gc(&m_buffer);
// we double buffer, so we paint on an image first, then from the image onto the canvas,
......
......@@ -87,11 +87,6 @@ public:
*/
TransferType transfer;
/**
* Render hints for painting the direct painting/patch painting
*/
QPainter::RenderHints renderHints;
/**
* The number of additional pixels those should be added
* to the patch
......
This diff is collapsed.
/*
Copyright (C) 2004, 2005, 2007
Daniel M. Duley <daniel.duley@verizon.net>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Portions of this software are were originally based on ImageMagick's
algorithms. ImageMagick is copyrighted under the following conditions:
Copyright (C) 2003 ImageMagick Studio, a non-profit organization dedicated to
making software imaging solutions freely available.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files ("ImageMagick"), to deal
in ImageMagick without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of ImageMagick, and to permit persons to whom the ImageMagick is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of ImageMagick.
The software is provided "as is", without warranty of any kind, express or
implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose and noninfringement. In no event shall
ImageMagick Studio be liable for any claim, damages or other liability,
whether in an action of contract, tort or otherwise, arising from, out of or
in connection with ImageMagick or the use or other dealings in ImageMagick.
Except as contained in this notice, the name of the ImageMagick Studio shall
not be used in advertising or otherwise to promote the sale, use or other
dealings in ImageMagick without prior written authorization from the
ImageMagick Studio.
*/
#include <QImage>
#ifndef SCALEFILTER_H
class Blitz
{
public:
enum ScaleFilterType{UndefinedFilter=0, PointFilter, BoxFilter,
TriangleFilter, HermiteFilter, HanningFilter, HammingFilter,
BlackmanFilter, GaussianFilter, QuadraticFilter, CubicFilter,
CatromFilter, MitchellFilter, LanczosFilter, BesselFilter,
SincFilter};
/**
* Smoothscales an image using a high-quality filter.
*
* @param img The image to smoothscale.
* @param sz The size to scale to.
* @param blur A blur factor. Values greater than 1.0 blur while values
* less than 1.0 sharpen.
* @param filter The filter type.
* @param aspectRatio What aspect ratio to use, if any.
* @return The processed image. The original is not changed.
* @author Daniel M. Duley (mosfet)
*/
static QImage smoothScaleFilter(QImage &img, const QSize &sz,
float blur=1.0,
ScaleFilterType filter=BlackmanFilter,
Qt::AspectRatioMode aspectRatio =
Qt::IgnoreAspectRatio);
static QImage smoothScaleFilter(QImage &img, int dwX, int dwY,
float blur=1.0,
ScaleFilterType filter=BlackmanFilter,
Qt::AspectRatioMode aspectRatio =
Qt::IgnoreAspectRatio);
};
#define SCALEFILTER_H
#endif // SCALEFILTER_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment