QuillImage TiltShift::apply(const QuillImage& image) const
{
    if (image.isNull()) {
        return image;
    }
    if (image.isFragment()) {
        m_gaussianFilter->setOption(QuillImageFilter::Radius, QVariant(GAUSSIAN_BLUR_RADIUS_TILE));
    } else if (image.size() == QSize(170, 170)) {
        m_gaussianFilter->setOption(QuillImageFilter::Radius, QVariant(GAUSSIAN_BLUR_RADIUS_THUMBNAIL));
    } else {
        m_gaussianFilter->setOption(QuillImageFilter::Radius, QVariant(GAUSSIAN_BLUR_RADIUS_PREVIEW));
    }
    QuillImage blurredImage = m_gaussianFilter->apply(image);

    float** mask = maskImage(image);
    QImage resultImage(image.size(), QImage::Format_RGB32);

    for (int y=0; y<image.height(); y++) {
        const QRgb* originalPixelRow = (const QRgb*)image.constScanLine(y);
        const QRgb* blurredPixelRow = (const QRgb*)blurredImage.constScanLine(y);
        QRgb* resultPixelRow = (QRgb*)resultImage.scanLine(y);

        for (int x=0; x<image.width(); x++) {
            int red = qRed(originalPixelRow[x]) * mask[x][y] + qRed(blurredPixelRow[x]) * (1 - mask[x][y]);
            int blue = qBlue(originalPixelRow[x]) * mask[x][y] + qBlue(blurredPixelRow[x]) * (1 - mask[x][y]);
            int green = qGreen(originalPixelRow[x]) * mask[x][y] + qGreen(blurredPixelRow[x]) * (1 - mask[x][y]);
            QColor result(red, green, blue);
            result.setHsvF(result.hueF(), qMin(SATURATION_FACTOR * result.saturationF(), 1.0), result.valueF());

            resultPixelRow[x] = result.rgb();
        }
    }

    for (int i = 0; i < image.size().width(); i ++) {
        delete[] mask[i];
    }

    delete[] mask;

    return QuillImage(image, resultImage);
}
Beispiel #2
0
QuillImage SaveFilter::apply(const QuillImage &image) const
{

    if(image.isNull())
        return QuillImage();
    // Simple format detection (1. given format 2. suffix)
    QString format = priv->fileFormatQt.toLatin1();
    if (format.isEmpty())
        format = QFileInfo(priv->fileName).suffix().toLatin1();

    // Jpeg always uses serial access saving, also for non-tiles,
    // to be able to insert EXIF data
    format = format.toLower();
    if ((format == "jpeg") || (format == "jpg"))
        return saveJpeg(image);

    // For non-tiles, just save
    if (!image.isFragment())
    {
        bool ok = saveFullImage(image);
        if (ok) {
            setFileModificationDateTime();
            return image;
        }
        else
            return QuillImage();
    }

    // First execute - prepare target

    if (priv->fullImageSize == QSize())
    {
            priv->fullImageSize = image.fullImageSize();

            priv->fullImage = QImage(priv->fullImageSize, QImage::Format_RGB32);
    }

    QPainter painter(&(priv->fullImage));
    painter.setCompositionMode(QPainter::CompositionMode_Source);

    painter.drawImage(image.area().topLeft(), image);

    priv->tileCount--;

    // Target full image has everything necessary, so do the final save.

    if (priv->tileCount == 0)
    {
        bool ok = saveFullImage(priv->fullImage);

        if (ok) {
            setFileModificationDateTime();
            // Return non-empty image to represent success
            return image;
        }
        else
            // Return empty image to represent failure
            return QuillImage();
    }
    else
        // No actual save was made, return non-empty image to represent success
        return image;
}