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(); } }
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(); }
bool WaterMark::toolOperations() { if (!loadToDImg()) { return false; } QString fileName = settings()[QLatin1String("Watermark image")].toString(); int placement = settings()[QLatin1String("Placement")].toInt(); int size = settings()[QLatin1String("Watermark size")].toInt(); int xMargin = settings()[QLatin1String("X margin")].toInt(); int yMargin = settings()[QLatin1String("Y margin")].toInt(); bool useImage = settings()[QLatin1String("Use image")].toBool(); QString text = settings()[QLatin1String("Text")].toString(); QFont font = settings()[QLatin1String("Font")].toString(); QColor fontColor = settings()[QLatin1String("Color")].toString(); int textOpacity = settings()[QLatin1String("Text opacity")].toInt(); bool useBackground = settings()[QLatin1String("Use background")].toBool(); QColor backgroundColor = settings()[QLatin1String("Background color")].toString(); int backgroundOpacity = settings()[QLatin1String("Background opacity")].toInt(); DImg watermarkImage; DColorComposer* composer = DColorComposer::getComposer(DColorComposer::PorterDuffNone); int marginW = lround(image().width() * (xMargin / 100.0)); int marginH = lround(image().height() * (yMargin / 100.0)); if (useImage) { watermarkImage = DImg(fileName); if (watermarkImage.isNull()) { return false; } DImg tempImage = watermarkImage.smoothScale(image().width() * size / 100, image().height() * size / 100, Qt::KeepAspectRatio); watermarkImage = tempImage; } else { int alignMode; const int radius = 10; if (text.isEmpty()) { return false; } int fontSize = queryFontSize(text, font, size); if (fontSize == 0) { return false; } switch (placement) { case Private::TopLeft: alignMode = Qt::AlignLeft; break; case Private::TopRight: alignMode = Qt::AlignRight; break; case Private::BottomLeft: alignMode = Qt::AlignLeft; break; case Private::Center: alignMode = Qt::AlignCenter; break; default : // BottomRight alignMode = Qt::AlignRight; break; } font.setPointSizeF(fontSize); QFontMetrics fontMt(font); QRect fontRect = fontMt.boundingRect(radius, radius, image().width(), image().height(), 0, text); // Add a transparent layer. QRect backgroundRect(fontRect.x() - radius, fontRect.y() - radius, fontRect.width() + 2 * radius, fontRect.height() + 2 * radius); DImg backgroundLayer(backgroundRect.width(), backgroundRect.height(), image().sixteenBit(), true); DColor transparent(QColor(0, 0, 0)); transparent.setAlpha(0); if (image().sixteenBit()) { transparent.convertToSixteenBit(); } backgroundLayer.fill(transparent); DImg grayTransLayer(fontRect.width(), fontRect.height(), image().sixteenBit(), true); if (useBackground) { DColor grayTrans(backgroundColor); grayTrans.setAlpha(backgroundOpacity * 255 / 100); if (image().sixteenBit()) { grayTrans.convertToSixteenBit(); } grayTransLayer.fill(grayTrans); backgroundLayer.bitBlendImage(composer, &grayTransLayer, 0, 0, grayTransLayer.width(), grayTransLayer.height(), radius, radius); } BlurFilter blur(&backgroundLayer, 0L, radius); blur.startFilterDirectly(); backgroundLayer.putImageData(blur.getTargetImage().bits()); // Draw text QImage img = backgroundLayer.copyQImage(fontRect); QPainter p(&img); fontColor.setAlpha(textOpacity * 255 / 100); p.setPen(QPen(fontColor, 1)); p.setFont(font); p.save(); p.drawText(0, 0, fontRect.width(), fontRect.height(), alignMode, text); p.restore(); p.end(); watermarkImage = DImg(img); } watermarkImage.convertToDepthOfImage(&image()); QRect watermarkRect(0, 0, watermarkImage.width(), watermarkImage.height()); switch (placement) { case Private::TopLeft: watermarkRect.moveTopLeft(QPoint(marginW, marginH)); break; case Private::TopRight: watermarkRect.moveTopRight(QPoint(image().width() - marginW, marginH)); break; case Private::BottomLeft: watermarkRect.moveBottomLeft(QPoint(marginW, image().height() - marginH)); break; case Private::Center: watermarkRect.moveCenter(QPoint((int)(image().width() / 2), (int)(image().height() / 2))); break; default : // BottomRight watermarkRect.moveBottomRight(QPoint(image().width() - marginW, image().height() - marginH)); break; } // TODO: Create watermark filter, move code there, implement FilterAction image().bitBlendImage(composer, &watermarkImage, 0, 0, watermarkImage.width(), watermarkImage.height(), watermarkRect.left(), watermarkRect.top()); delete composer; return (savefromDImg()); }