Пример #1
0
void LensAutoFixTool::preparePreview()
{
    // Settings information must be get before to disable settings view.
    LensFunContainer settings = d->cameraSelector->settings();
    d->settingsView->assignFilterSettings(settings);
    ImageIface* const iface   = d->previewWidget->imageIface();
    DImg preview              = iface->preview();

    if (d->showGrid->isChecked())
    {
        QBitmap pattern(9, 9);
        pattern.clear();
        QPainter p1(&pattern);
        p1.setPen(QPen(Qt::black, 1));
        p1.drawLine(5, 0, 5, 9);
        p1.drawLine(0, 5, 9, 5);
        p1.end();

        QPixmap pix(preview.size());
        pix.fill(Qt::transparent);
        QPainter p2(&pix);
        p2.setPen(QPen(Qt::gray, 1));
        p2.fillRect(0, 0, pix.width(), pix.height(), QBrush(pattern));
        p2.end();
        DImg grid(pix.toImage());

        DColorComposer* const composer            = DColorComposer::getComposer(DColorComposer::PorterDuffNone);
        DColorComposer::MultiplicationFlags flags = DColorComposer::NoMultiplication;

        // Do alpha blending of template on dest image
        preview.bitBlendImage(composer, &grid, 0, 0, preview.width(), preview.height(), 0, 0, flags);
    }

    setFilter(new LensFunFilter(&preview, this, settings));
}
Пример #2
0
DImg SharedLoadSaveThread::cacheLookup(const QString& filePath, AccessMode /*accessMode*/)
{
    LoadingCache* cache = LoadingCache::cache();
    LoadingCache::CacheLock lock(cache);
    DImg* cachedImg = cache->retrieveImage(filePath);

    // Qt4: uncomment this code.
    // See comments in SharedLoadingTask::execute for explanation.

    /*
    if (cachedImg)
    {
        if (accessMode == AccessModeReadWrite)
            return cachedImg->copy();
        else
            return *cachedImg;
    }
    else
        return DImg();
    */
    if (cachedImg)
    {
        return cachedImg->copy();
    }
    else
    {
        return DImg();
    }
}
Пример #3
0
void ImageQualityTask::run()
{
    if (!d->cancel)
    {
        // Get item preview to perform quality analysis. No need to load whole image, this will be slower.
        // TODO : check if 1024 pixels size is enough to get suitable Quality results.
        DImg dimg = PreviewLoadThread::loadFastSynchronously(d->path, 1024);

        if (!dimg.isNull() && !d->cancel)
        {
            // TODO : run here Quality analysis backend and store Pick Label result to DB.
            // Backend Input : d->quality as Quality analysis settings,
            //                 dimg       as reduced size image data to parse,
            //                 d->path    as file path to patch DB properties.
            // Result        : Backend must scan Quality of image depending of settings and compute a Quality estimation accordingly.
            //                 Finaly, using file path, DB Pick Label properties must be assigned through ImageInfo interface.
            // Warning       : All code here will run in a separated thread and must be re-entrant/thread-safe. Only pure computation
            //                 must be processed. GUI calls are prohibited. ImageInfo and DImg can be used safety in thread.

            PickLabel pick;
            d->imgqsort = new ImgQSort(dimg, d->quality, &pick);
            d->imgqsort->startAnalyse();

            ImageInfo info = ImageInfo::fromLocalFile(d->path);
            info.setPickLabel(pick);

            delete d->imgqsort; //delete image data after setting label
            d->imgqsort = 0;
        }
        // Dispatch progress to Progress Manager
        QImage qimg = dimg.smoothScale(22, 22, Qt::KeepAspectRatio).copyQImage();
        emit signalFinished(qimg);
        emit signalDone();
    }
}
Пример #4
0
void ShearTool::setPreviewImage()
{
    ImageIface* const iface = d->previewWidget->imageIface();
    int w                   = iface->previewSize().width();
    int h                   = iface->previewSize().height();
    DImg imTemp             = filter()->getTargetImage().smoothScale(w, h, Qt::KeepAspectRatio);
    DImg imDest( w, h, filter()->getTargetImage().sixteenBit(), filter()->getTargetImage().hasAlpha() );

    imDest.fill( DColor(d->previewWidget->palette().color(QPalette::Background).rgb(),
                        filter()->getTargetImage().sixteenBit()) );
    imDest.bitBltImage(&imTemp, (w-imTemp.width())/2, (h-imTemp.height())/2);

    iface->setPreview(imDest.smoothScale(iface->previewSize()));

    d->previewWidget->updatePreview();

    ShearFilter* const tool = dynamic_cast<ShearFilter*>(filter());

    if (tool)
    {
        QSize newSize = tool->getNewSize();
        QString temp;
        d->newWidthLabel->setText(temp.setNum( newSize.width())   + i18n(" px") );
        d->newHeightLabel->setText(temp.setNum( newSize.height()) + i18n(" px") );
    }
}
Пример #5
0
void ContentAwareResizeTool::prepareEffect()
{
    if (d->prevW  != d->wInput->value()  || d->prevH  != d->hInput->value() ||
        d->prevWP != d->wpInput->value() || d->prevHP != d->hpInput->value())
    {
        slotValuesChanged();
    }

    disableSettings();

    ImageIface* iface = d->previewWidget->imageIface();
    int w             = iface->previewWidth();
    int h             = iface->previewHeight();
    DImg imTemp       = iface->getOriginalImg()->smoothScale(w, h, Qt::KeepAspectRatio);
    int new_w         = (int)(w*d->wpInput->value()/100.0);
    int new_h         = (int)(h*d->hpInput->value()/100.0);

    if (d->mixedRescaleInput->value()<100.0) // mixed rescale
    {
        double stdRescaleP = (100.0 - d->mixedRescaleInput->value()) / 100.0;
        int diff_w         = (int)(stdRescaleP * (w - new_w));
        int diff_h         = (int)(stdRescaleP * (h - new_h));

        imTemp.resize(imTemp.width() - diff_w, imTemp.height() - diff_h);
    }

    QImage mask;

    if (d->weightMaskBox->isChecked())
    {
        mask = d->previewWidget->getMask();
    }

    contentAwareResizeCore(&imTemp, new_w, new_h, mask);
}
Пример #6
0
int LoadSaveThread::exifOrientation(const DImg& image, const QString& filePath)
{
    QVariant attribute = image.attribute("fromRawEmbeddedPreview");
    return exifOrientation(filePath, DMetadata(image.getMetadata()),
                           image.detectedFormat() == DImg::RAW,
                           (attribute.isValid() && attribute.toBool()));
}
Пример #7
0
bool MetadataHub::write(DImg& image, WriteComponent writeMode, bool ignoreLazySync, const MetadataSettingsContainer& settings)
{
    applyChangeNotifications();

    // if no DMetadata object is needed at all, don't construct one
    if (!willWriteMetadata(writeMode, settings))
    {
        return false;
    }

    // See DImgLoader::readMetadata() and saveMetadata()
    DMetadata metadata;
    metadata.setData(image.getMetadata());

    QString filePath = image.originalFilePath();

    if (filePath.isEmpty())
    {
        filePath = image.lastSavedFilePath();
    }

    if (!ignoreLazySync && settings.useLazySync && !filePath.isEmpty())
    {
        ImageInfo info = ImageInfo::fromLocalFile(filePath);
        MetadataHubMngr::instance()->addPending(info);
        return true;
    }

    if (!filePath.isEmpty())
    {
        writeToBaloo(filePath);
    }

    return write(metadata, writeMode, settings);
}
Пример #8
0
void UndoManager::getSnapshot(int index, DImg* const img) const
{
    DImg data = d->undoCache->getData(index);

    // Pass ownership of buffer. If data is null, img will be null
    img->putImageData(data.width(), data.height(), data.sixteenBit(), data.hasAlpha(), data.bits(), true);
}
Пример #9
0
void RainDropTool::putPreviewData()
{
    ImageIface* iface = d->previewWidget->imageIface();
    DImg imDest       = filter()->getTargetImage().smoothScale(iface->previewWidth(), iface->previewHeight());
    iface->putPreviewImage(imDest.bits());

    d->previewWidget->updatePreview();
}
Пример #10
0
void UndoManager::restoreSnapshot(int index, const UndoMetadataContainer& c)
{
    DImg img = d->undoCache->getData(index);

    if (!img.isNull())
    {
        d->core->setUndoImg(c, img);
    }
}
Пример #11
0
void InsertTextWidget::makePixmap()
{
    int orgW = d->iface->originalSize().width();
    int orgH = d->iface->originalSize().height();
    float ratioW = (float)d->w / (float)orgW;
    float ratioH = (float)d->h / (float)orgH;

    int x, y;

    if (d->textRect.isValid())
    {
        // convert from widget to image coordinates
        x = d->textRect.x() - d->rect.x();
        y = d->textRect.y() - d->rect.y();
    }
    else
    {
        x = -1;
        y = -1;
    }

    // get preview image data
    DImg image = d->iface->preview();
    image.setIccProfile( d->iface->original()->getIccProfile() );

    // paint pixmap for drawing this widget
    // First, fill with background color
    d->pixmap->fill(d->bgColor);
    QPainter p(d->pixmap);

    // Convert image to pixmap and draw it
    QPixmap imagePixmap = d->iface->convertToPixmap(image);
    p.drawPixmap(d->rect.x(), d->rect.y(),
                 imagePixmap, 0, 0, imagePixmap.width(), imagePixmap.height());

    // prepare painter for use by compose image
    p.setClipRect(d->rect);
    p.translate(d->rect.x(), d->rect.y());

    int borderWidth = qMax(1, qRound(ratioW));

    // compose image and draw result directly on pixmap, with correct offset
    QRect textRect = composeImage(&image, &p, x, y,
                                  d->textFont, d->textFont.pointSizeF(),
                                  d->textRotation, d->textColor, d->textOpacity,
                                  d->alignMode, d->textString, d->textTransparent, d->backgroundColor,
                                  d->textBorder ? BORDER_NORMAL : BORDER_SUPPORT, borderWidth, borderWidth,
                                  (ratioW > ratioH) ? ratioW : ratioH);

    p.end();

    // store new text rectangle
    // convert from image to widget coordinates
    d->textRect.setX(textRect.x() + d->rect.x());
    d->textRect.setY(textRect.y() + d->rect.y());
    d->textRect.setSize(textRect.size());
}
Пример #12
0
void WhiteBalanceTool::setPreviewImage()
{
    DImg preview = filter()->getTargetImage();
    d->previewWidget->setPreviewImage(preview);

    // Update histogram.

    d->gboxSettings->histogramBox()->histogram()->updateData(preview.copy(), DImg(), false);
}
Пример #13
0
void ResizeTool::putFinalData()
{
    ImageIface iface(0, 0);
    DImg targetImage = filter()->getTargetImage();
    iface.putOriginalImage(i18n("Resize"),
                           filter()->filterAction(),
                           targetImage.bits(),
                           targetImage.width(), targetImage.height());
}
Пример #14
0
void BCGFilter::applyBCG(DImg& image)
{
    if (image.isNull())
    {
        return;
    }

    applyBCG(image.bits(), image.width(), image.height(), image.sixteenBit());
}
Пример #15
0
void IccTransform::transform(DImg& image, const TransformDescription& description, DImgLoaderObserver* const observer)
{
    const int bytesDepth    = image.bytesDepth();
    const int pixels        = image.width() * image.height();
    // convert ten scanlines in a batch
    const int pixelsPerStep = image.width() * 10;
    uchar* data             = image.bits();

    // see dimgloader.cpp, granularity().
    int granularity         = 1;

    if (observer)
    {
        granularity = (int)((pixels / (20 * 0.9)) / observer->granularity());
    }

    int checkPoint = pixels;

    // it is safe to use the same input and output buffer if the format is the same
    if (description.inputFormat == description.outputFormat)
    {
        for (int p = pixels; p > 0; p -= pixelsPerStep)
        {
            int pixelsThisStep =  qMin(p, pixelsPerStep);
            int size           =  pixelsThisStep * bytesDepth;
            LcmsLock lock;
            dkCmsDoTransform(d->handle, data, data, pixelsThisStep);
            data               += size;

            if (observer && p <= checkPoint)
            {
                checkPoint -= granularity;
                observer->progressInfo(&image, 0.1 + 0.9 * (1.0 - float(p) / float(pixels)));
            }
        }
    }
    else
    {
        QVarLengthArray<uchar> buffer(pixelsPerStep * bytesDepth);

        for (int p = pixels; p > 0; p -= pixelsPerStep)
        {
            int pixelsThisStep  = qMin(p, pixelsPerStep);
            int size            = pixelsThisStep * bytesDepth;
            LcmsLock lock;
            memcpy(buffer.data(), data, size);
            dkCmsDoTransform(d->handle, buffer.data(), data, pixelsThisStep);
            data               += size;

            if (observer && p <= checkPoint)
            {
                checkPoint -= granularity;
                observer->progressInfo(&image, 0.1 + 0.9 * (1.0 - float(p) / float(pixels)));
            }
        }
    }
}
Пример #16
0
bool IccTransform::apply(DImg& image, DImgLoaderObserver* const observer)
{
    if (!willHaveEffect())
    {
        if (!d->outputProfile.isNull() && !d->doNotEmbed)
        {
            image.setIccProfile(d->outputProfile);
        }

        return true;
    }

    if (!checkProfiles())
    {
        return false;
    }

    TransformDescription description;

    if (d->proofProfile.isNull())
    {
        description = getDescription(image);

        if (!open(description))
        {
            return false;
        }
    }
    else
    {
        description = getProofingDescription(image);

        if (!openProofing(description))
        {
            return false;
        }
    }

    if (observer)
    {
        observer->progressInfo(&image, 0.1F);
    }

    transform(image, description, observer);

    if (!d->doNotEmbed)
    {
        image.setIccProfile(d->outputProfile);
    }

    // if this was a RAW color image, it is no more
    image.removeAttribute(QLatin1String("uncalibratedColor"));

    return true;
}
Пример #17
0
void BWSepiaFilter::applyToneFilter(DImg& img, TonalityContainer& settings)
{
    // Value to multiply RGB 8 bits component of mask used by TonalityFilter.
    int mul            = img.sixteenBit() ? 255 : 1;
    settings.redMask   = settings.redMask   * mul;
    settings.greenMask = settings.greenMask * mul;
    settings.blueMask  = settings.blueMask  * mul;
    TonalityFilter tone(&img, 0L, settings);
    tone.startFilterDirectly();
    img.putImageData(tone.getTargetImage().bits());
}
Пример #18
0
void RawImport::setPreviewImage()
{
    // Preserve metadata from loaded image, and take post-processed image data
    d->postProcessedImage = d->previewWidget->demosaicedImage().copyMetaData();
    DImg data             = filter()->getTargetImage();
    d->postProcessedImage.putImageData(data.width(), data.height(), data.sixteenBit(), data.hasAlpha(),
                                       data.stripImageData(), false);
    d->previewWidget->setPostProcessedImage(d->postProcessedImage);
    d->settingsBox->setPostProcessedImage(d->postProcessedImage);
    EditorToolIface::editorToolIface()->setToolStopProgress();
    setBusy(false);
}
Пример #19
0
void DImageFilterActionTest::testActions()
{
    QStringList files = QDir(imagePath()).entryList(QDir::Files);
    files.removeOne(originalImage());

    DImg original(imagePath() + originalImage());
    QVERIFY(!original.isNull());

    foreach (const QString& fileName, files)
    {
        DImg ref(imagePath() + fileName);
        QVERIFY(!ref.isNull());
        DImageHistory history = ref.getImageHistory();

        FilterActionFilter filter;
        filter.setFilterActions(history.allActions());
        QVERIFY(filter.isReproducible() || filter.isComplexAction());

        filter.setupFilter(original.copy());
        filter.startFilterDirectly();
        qDebug() << filter.filterActions().size();

        DImg img = filter.getTargetImage();

        QVERIFY(ref.size() == img.size());

        bool isEqual = true;
        DImg diff(ref.width(), ref.height(), ref.sixteenBit());
        diff.fill(DColor(Qt::black));

        for (uint x=0; x<ref.width(); x++)
        {
            for (uint y=0; y<ref.height(); y++)
            {
                DColor cref = ref.getPixelColor(x,y);
                DColor cres = img.getPixelColor(x,y);

                if (cref.red() != cres.red() || cref.green() != cres.green() || cref.blue() != cres.blue())
                {
                    //qDebug() << x << y;
                    diff.setPixelColor(x,y, DColor(Qt::white));
                    isEqual = false;
                }
            }
        }

        if (!isEqual)
        {
            showDiff(original, ref, img, diff);
        }

        QVERIFY(isEqual);
    }
Пример #20
0
bool LoadSaveThread::exifRotate(DImg& image, const QString& filePath)
{
    // Keep in sync with the variant in thumbnailcreator.cpp
    if (wasExifRotated(image))
    {
        return false;
    }

    // Rotate thumbnail based on metadata orientation information

    bool rotatedOrFlipped = image.rotateAndFlip(exifOrientation(image, filePath));
    image.setAttribute("exifRotated", true);

    return rotatedOrFlipped;
}
Пример #21
0
void ResizeTool::putPreviewData()
{
    ImageIface* iface = d->previewWidget->imageIface();
    int w             = iface->previewWidth();
    int h             = iface->previewHeight();
    DImg imTemp       = filter()->getTargetImage().smoothScale(w, h, Qt::KeepAspectRatio);
    DImg imDest(w, h, filter()->getTargetImage().sixteenBit(), filter()->getTargetImage().hasAlpha());

    QColor background = toolView()->backgroundRole();
    imDest.fill(DColor(background, filter()->getTargetImage().sixteenBit()));
    imDest.bitBltImage(&imTemp, (w-imTemp.width())/2, (h-imTemp.height())/2);

    iface->putPreviewImage((imDest.smoothScale(iface->previewWidth(), iface->previewHeight())).bits());
    d->previewWidget->updatePreview();
}
Пример #22
0
QImage DImg::copyQImage(int x, int y, int w, int h) const
{
    if (isNull())
    {
        return QImage();
    }

    DImg img = copy(x, y, w, h);

    if (img.sixteenBit())
    {
        img.convertDepth(32);
    }

    return img.copyQImage();
}
Пример #23
0
DImg BWSepiaFilter::getThumbnailForEffect(DImg& img)
{
    postProgress(10);
    DImg thumb = img.copy();

    postProgress(25);

    if (d->settings.previewType < BWSepiaContainer::BWGeneric)
    {
        // In Filter view, we will render a preview of the B&W filter with the generic B&W film.

        blackAndWhiteConversion(thumb, d->settings.previewType);
        postProgress(50);

        blackAndWhiteConversion(thumb, BWSepiaContainer::BWGeneric);
        postProgress(75);
    }
    else
    {
        // In Film and Tone view, we will render the preview without to use the B&W Filter.

        postProgress(50);

        blackAndWhiteConversion(thumb, d->settings.previewType);
        postProgress(75);
    }

    postProgress(90);

    return (thumb);
}
Пример #24
0
bool LoadSaveThread::wasExifRotated(DImg& image)
{
    // Keep in sync with the variant in thumbnailcreator.cpp
    QVariant attribute(image.attribute("exifRotated"));

    return attribute.isValid() && attribute.toBool();
}
Пример #25
0
void DImgPreviewItem::slotGotImagePreview(const LoadingDescription& description, const DImg& image)
{
    Q_D(DImgPreviewItem);

    if (description.filePath != d->path || description.isThumbnail())
    {
        return;
    }

    setImage(image);

    if (image.isNull())
    {
        d->state = ImageLoadingFailed;
        emit stateChanged(d->state);
        emit loadingFailed();
    }
    else
    {
        d->state = ImageLoaded;
        emit stateChanged(d->state);
        emit loaded();
    }

    preloadNext();
}
Пример #26
0
uchar* ImageIface::Private::previewImageData()
{
    if (previewImage.isNull())
    {
        DImg* im = 0;

        if (previewType == FullImage)
        {
            im = core->getImg();

            if (!im || im->isNull())
            {
                return 0;
            }
        }
        else  // ImageSelection
        {
            im = new DImg(core->getImgSelection());

            if (!im)
            {
                return 0;
            }

            if (im->isNull())
            {
                delete im;
                return 0;
            }

            im->setIccProfile(core->getEmbeddedICC());
        }

        QSize sz(im->width(), im->height());
        sz.scale(constrainWidth, constrainHeight, Qt::KeepAspectRatio);

        previewImage       = im->smoothScale(sz.width(), sz.height());
        previewWidth       = previewImage.width();
        previewHeight      = previewImage.height();

        // only create another copy if needed, in setPreviewImage
        targetPreviewImage = previewImage;

        if (previewType == ImageSelection)
        {
            delete im;
        }
    }

    DImg previewData = previewImage.copyImageData();
    return previewData.stripImageData();
}
Пример #27
0
void ImageIface::setSelection(const QString& caller, const FilterAction& action, const DImg& img)
{
    if (img.hasAlpha()   != originalHasAlpha()     ||
        img.sixteenBit() != originalSixteenBit()   ||
        img.size()       != selectionRect().size()
       )
    {
        kDebug() << "Properties of image to overwrite selection differs than original image";
        return;
    }

    if (img.isNull())
    {
        kDebug() << "No image data to handle";
        return;
    }

    d->core->putImgSelection(caller, action, img);
}
Пример #28
0
void ImageIface::setOriginal(const QString& caller, const FilterAction& action, const DImg& img)
{
    if (img.isNull())
    {
        kDebug() << "No image data to handle";
        return;
    }

    d->core->putImg(caller, action, img);
}
Пример #29
0
void Canvas::slotCopy()
{
    QRect sel = d->core->getSelectedArea();

    if (sel.size().isNull())   // No current selection.
    {
        return;
    }

    QApplication::setOverrideCursor(Qt::WaitCursor);

    DImg selDImg              = d->core->getImgSelection();
    QImage selImg             = selDImg.copyQImage();
    QMimeData* const mimeData = new QMimeData();
    mimeData->setImageData(selImg);
    QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);

    QApplication::restoreOverrideCursor();
}
Пример #30
0
void DImgBuiltinFilter::apply(DImg& image) const
{
    switch (m_type)
    {
        case NoOperation:
            break;

        case Rotate90:
            image.rotate(DImg::ROT90);
            break;

        case Rotate180:
            image.rotate(DImg::ROT180);
            break;

        case Rotate270:
            image.rotate(DImg::ROT270);
            break;

        case FlipHorizontally:
            image.flip(DImg::HORIZONTAL);
            break;

        case FlipVertically:
            image.flip(DImg::VERTICAL);
            break;

        case Crop:
            image.crop(m_arg.toRect());
            break;

        case Resize:
        {
            QSize s = m_arg.toSize();
            image.resize(s.width(), s.height());
            break;
        }

        case ConvertTo8Bit:
            image.convertToEightBit();
            break;

        case ConvertTo16Bit:
            image.convertToSixteenBit();
            break;
    }
}