inline static FloatRgb safeGetPixel(const QImage &image, int x, int y) { return image.valid(x, y) ? image.pixel(x, y) : qRgba(0, 0, 0, 0); }
void dviRenderer::set_char(unsigned int cmd, unsigned int ch) { #ifdef DEBUG_RENDER kDebug(kvs::dvi) << "set_char #" << ch; #endif glyph *g; if (colorStack.isEmpty()) g = ((TeXFont *)(currinf.fontp->font))->getGlyph(ch, true, globalColor); else g = ((TeXFont *)(currinf.fontp->font))->getGlyph(ch, true, colorStack.top()); if (g == NULL) return; long dvi_h_sav = currinf.data.dvi_h; QImage pix = g->shrunkenCharacter; int x = ((int) ((currinf.data.dvi_h) / (shrinkfactor * 65536))) - g->x2; int y = currinf.data.pxl_v - g->y2; // Draw the character. foreGroundPainter->drawImage(x, y, pix); // Are we drawing text for a hyperlink? And are hyperlinks // enabled? if (HTML_href != NULL) { // Now set up a rectangle which is checked against every mouse // event. if (line_boundary_encountered == true) { // Set up hyperlink Hyperlink dhl; dhl.baseline = currinf.data.pxl_v; dhl.box.setRect(x, y, pix.width(), pix.height()); dhl.linkText = *HTML_href; currentlyDrawnPage->hyperLinkList.push_back(dhl); } else { QRect dshunion = currentlyDrawnPage->hyperLinkList[currentlyDrawnPage->hyperLinkList.size()-1].box.unite(QRect(x, y, pix.width(), pix.height())) ; currentlyDrawnPage->hyperLinkList[currentlyDrawnPage->hyperLinkList.size()-1].box = dshunion; } } // Are we drawing text for a source hyperlink? And are source // hyperlinks enabled? // If we are printing source hyperlinks are irrelevant, otherwise we // actually got a pointer to a RenderedDviPagePixmap. RenderedDviPagePixmap* currentDVIPage = dynamic_cast<RenderedDviPagePixmap*>(currentlyDrawnPage); if (source_href != 0 && currentDVIPage) { // Now set up a rectangle which is checked against every mouse // event. if (line_boundary_encountered == true) { // Set up source hyperlinks Hyperlink dhl; dhl.baseline = currinf.data.pxl_v; dhl.box.setRect(x, y, pix.width(), pix.height()); if (source_href != NULL) dhl.linkText = *source_href; else dhl.linkText = ""; currentDVIPage->sourceHyperLinkList.push_back(dhl); } else { QRect dshunion = currentDVIPage->sourceHyperLinkList[currentDVIPage->sourceHyperLinkList.size()-1].box.unite(QRect(x, y, pix.width(), pix.height())) ; currentDVIPage->sourceHyperLinkList[currentDVIPage->sourceHyperLinkList.size()-1].box = dshunion; } } // Code for DVI -> text functions (e.g. marking of text, full text // search, etc.). Set up the currentlyDrawnPage->textBoxList. TextBox link; link.box.setRect(x, y, pix.width(), pix.height()); link.text = ""; currentlyDrawnPage->textBoxList.push_back(link); switch(ch) { case 0x0b: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += "ff"; break; case 0x0c: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += "fi"; break; case 0x0d: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += "fl"; break; case 0x0e: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += "ffi"; break; case 0x0f: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += "ffl"; break; case 0x7b: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += '-'; break; case 0x7c: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += "---"; break; case 0x7d: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += "\""; break; case 0x7e: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += '~'; break; case 0x7f: currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += "@@"; // @@@ check! break; default: if ((ch >= 0x21) && (ch <= 0x7a)) currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += QChar(ch); else currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += '?'; break; } if (cmd == PUT1) currinf.data.dvi_h = dvi_h_sav; else currinf.data.dvi_h += (int)(currinf.fontp->scaled_size_in_DVI_units * dviFile->getCmPerDVIunit() * (1200.0 / 2.54)/16.0 * g->dvi_advance_in_units_of_design_size_by_2e20 + 0.5); word_boundary_encountered = false; line_boundary_encountered = false; }
QFileInfo Content::GetAlbumArt( int nTrackId, int nWidth, int nHeight ) { // ---------------------------------------------------------------------- // Read AlbumArt file path from database // ---------------------------------------------------------------------- MusicMetadata *metadata = MusicMetadata::createFromID(nTrackId); if (!metadata) return QFileInfo(); QString sFullFileName = metadata->getAlbumArtFile(); LOG(VB_GENERAL, LOG_DEBUG, QString("GetAlbumArt: %1").arg(sFullFileName)); delete metadata; if (!RemoteFile::Exists(sFullFileName)) return QFileInfo(); QString sNewFileName = QString( "/tmp/%1.%2x%3.jpg" ) .arg( QFileInfo(sFullFileName).fileName() ) .arg( nWidth ) .arg( nHeight ); // ---------------------------------------------------------------------- // check to see if albumart image is already created. // ---------------------------------------------------------------------- if (QFile::exists( sNewFileName )) return QFileInfo( sNewFileName ); // ---------------------------------------------------------------------- // Must generate Albumart Image, Generate Image and save. // ---------------------------------------------------------------------- QImage img; if (sFullFileName.startsWith("myth://")) { RemoteFile rf(sFullFileName, false, false, 0); QByteArray data; rf.SaveAs(data); img.loadFromData(data); } else img.load(sFullFileName); if (img.isNull()) return QFileInfo(); // We don't need to scale if no height and width were specified // but still need to save as jpg if it's in another format if ((nWidth == 0) && (nHeight == 0)) { if (!sFullFileName.startsWith("myth://")) { QFileInfo fi(sFullFileName); if (fi.suffix().toLower() == "jpg") return fi; } } else if (nWidth > img.width() && nHeight > img.height()) { // Requested dimensions are larger than the source image, so instead of // scaling up which will produce horrible results return the fullsize // image and the user can scale further if they want instead // NOTE: If this behaviour is changed, for example making it optional, // then upnp code will need changing to compensate } else { float fAspect = 0.0; if (fAspect <= 0) fAspect = (float)(img.width()) / img.height(); if ( nWidth == 0 || nWidth > img.width() ) nWidth = (int)rint(nHeight * fAspect); if ( nHeight == 0 || nHeight > img.height() ) nHeight = (int)rint(nWidth / fAspect); img = img.scaled( nWidth, nHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); } QString fname = sNewFileName.toLatin1().constData(); // Use JPG not PNG for compatibility with the most uPnP devices and // faster loading (smaller file to send over network) if (!img.save( fname, "JPG" )) return QFileInfo(); return QFileInfo( sNewFileName ); }
static void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0) { if (screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) { double file_gamma; png_get_gAMA(png_ptr, info_ptr, &file_gamma); png_set_gamma(png_ptr, screen_gamma, file_gamma); } png_uint_32 width; png_uint_32 height; int bit_depth; int color_type; png_bytep trans_alpha = 0; png_color_16p trans_color_p = 0; int num_trans; png_colorp palette = 0; int num_palette; int interlace_method; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_method, 0, 0); png_set_interlace_handling(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY) { // Black & White or 8-bit grayscale if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) { png_set_invert_mono(png_ptr); png_read_update_info(png_ptr, info_ptr); if (image.size() != QSize(width, height) || image.format() != QImage::Format_Mono) { image = QImage(width, height, QImage::Format_Mono); if (image.isNull()) return; } image.setColorCount(2); image.setColor(1, qRgb(0,0,0)); image.setColor(0, qRgb(255,255,255)); } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_expand(png_ptr); png_set_strip_16(png_ptr); png_set_gray_to_rgb(png_ptr); if (image.size() != QSize(width, height) || image.format() != QImage::Format_ARGB32) { image = QImage(width, height, QImage::Format_ARGB32); if (image.isNull()) return; } if (QSysInfo::ByteOrder == QSysInfo::BigEndian) png_set_swap_alpha(png_ptr); png_read_update_info(png_ptr, info_ptr); } else { if (bit_depth == 16) png_set_strip_16(png_ptr); else if (bit_depth < 8) png_set_packing(png_ptr); int ncols = bit_depth < 8 ? 1 << bit_depth : 256; png_read_update_info(png_ptr, info_ptr); if (image.size() != QSize(width, height) || image.format() != QImage::Format_Indexed8) { image = QImage(width, height, QImage::Format_Indexed8); if (image.isNull()) return; } image.setColorCount(ncols); for (int i=0; i<ncols; i++) { int c = i*255/(ncols-1); image.setColor(i, qRgba(c,c,c,0xff)); } if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) { const int g = trans_color_p->gray; if (g < ncols) { image.setColor(g, 0); } } } } else if (color_type == PNG_COLOR_TYPE_PALETTE && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) && num_palette <= 256) { // 1-bit and 8-bit color if (bit_depth != 1) png_set_packing(png_ptr); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); QImage::Format format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8; if (image.size() != QSize(width, height) || image.format() != format) { image = QImage(width, height, format); if (image.isNull()) return; } png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); image.setColorCount(num_palette); int i = 0; if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) { while (i < num_trans) { image.setColor(i, qRgba( palette[i].red, palette[i].green, palette[i].blue, trans_alpha[i] ) ); i++; } } while (i < num_palette) { image.setColor(i, qRgba( palette[i].red, palette[i].green, palette[i].blue, 0xff ) ); i++; } } else { // 32-bit if (bit_depth == 16) png_set_strip_16(png_ptr); png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); QImage::Format format = QImage::Format_ARGB32; // Only add filler if no alpha, or we can get 5 channel data. if (!(color_type & PNG_COLOR_MASK_ALPHA) && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_filler(png_ptr, 0xff, QSysInfo::ByteOrder == QSysInfo::BigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER); // We want 4 bytes, but it isn't an alpha channel format = QImage::Format_RGB32; } QSize outSize(width,height); if (!scaledSize.isEmpty() && quint32(scaledSize.width()) <= width && quint32(scaledSize.height()) <= height && interlace_method == PNG_INTERLACE_NONE) { // Do inline downscaling outSize = scaledSize; if (doScaledRead) *doScaledRead = true; } if (image.size() != outSize || image.format() != format) { image = QImage(outSize, format); if (image.isNull()) return; } if (QSysInfo::ByteOrder == QSysInfo::BigEndian) png_set_swap_alpha(png_ptr); png_read_update_info(png_ptr, info_ptr); } // Qt==ARGB==Big(ARGB)==Little(BGRA) if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { png_set_bgr(png_ptr); } }
bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, const QString &description, int off_x_in, int off_y_in) { QPoint offset = image.offset(); int off_x = off_x_in + offset.x(); int off_y = off_y_in + offset.y(); png_structp png_ptr; png_infop info_ptr; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { return false; } png_set_error_fn(png_ptr, 0, 0, qt_png_warning); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, 0); return false; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return false; } int quality = quality_in; if (quality >= 0) { if (quality > 9) { qWarning("PNG: Quality %d out of range", quality); quality = 9; } png_set_compression_level(png_ptr, quality); } png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); int color_type = 0; if (image.colorCount()) { if (image.isGrayscale()) color_type = PNG_COLOR_TYPE_GRAY; else color_type = PNG_COLOR_TYPE_PALETTE; } else if (image.hasAlphaChannel()) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else color_type = PNG_COLOR_TYPE_RGB; png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), image.depth() == 1 ? 1 : 8, // per channel color_type, 0, 0, 0); // sets #channels if (gamma != 0.0) { png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); } if (image.format() == QImage::Format_MonoLSB) png_set_packswap(png_ptr); if (color_type == PNG_COLOR_TYPE_PALETTE) { // Paletted int num_palette = qMin(256, image.colorCount()); png_color palette[256]; png_byte trans[256]; int num_trans = 0; for (int i=0; i<num_palette; i++) { QRgb rgba=image.color(i); palette[i].red = qRed(rgba); palette[i].green = qGreen(rgba); palette[i].blue = qBlue(rgba); trans[i] = qAlpha(rgba); if (trans[i] < 255) { num_trans = i+1; } } png_set_PLTE(png_ptr, info_ptr, palette, num_palette); if (num_trans) { png_set_tRNS(png_ptr, info_ptr, trans, num_trans, 0); } } // Swap ARGB to RGBA (normal PNG format) before saving on // BigEndian machines if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { png_set_swap_alpha(png_ptr); } // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless if (QSysInfo::ByteOrder == QSysInfo::LittleEndian && image.format() != QImage::Format_RGB888) { png_set_bgr(png_ptr); } if (off_x || off_y) { png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL); } if (frames_written > 0) png_set_sig_bytes(png_ptr, 8); if (image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0) { png_set_pHYs(png_ptr, info_ptr, image.dotsPerMeterX(), image.dotsPerMeterY(), PNG_RESOLUTION_METER); } set_text(image, png_ptr, info_ptr, description); png_write_info(png_ptr, info_ptr); if (image.depth() != 1) png_set_packing(png_ptr); if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888) png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER); if (looping >= 0 && frames_written == 0) { uchar data[13] = "NETSCAPE2.0"; // 0123456789aBC data[0xB] = looping%0x100; data[0xC] = looping/0x100; png_write_chunk(png_ptr, (png_byte*)"gIFx", data, 13); } if (ms_delay >= 0 || disposal!=Unspecified) { uchar data[4]; data[0] = disposal; data[1] = 0; data[2] = (ms_delay/10)/0x100; // hundredths data[3] = (ms_delay/10)%0x100; png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4); } int height = image.height(); int width = image.width(); switch (image.format()) { case QImage::Format_Mono: case QImage::Format_MonoLSB: case QImage::Format_Indexed8: case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_RGB888: { png_bytep* row_pointers = new png_bytep[height]; for (int y=0; y<height; y++) row_pointers[y] = (png_bytep)image.constScanLine(y); png_write_image(png_ptr, row_pointers); delete [] row_pointers; } break; default: { QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32; QImage row; png_bytep row_pointers[1]; for (int y=0; y<height; y++) { row = image.copy(0, y, width, 1).convertToFormat(fmt); row_pointers[0] = png_bytep(row.constScanLine(0)); png_write_rows(png_ptr, row_pointers, 1); } } break; } png_write_end(png_ptr, info_ptr); frames_written++; png_destroy_write_struct(&png_ptr, &info_ptr); return true; }
static void read_jpeg_image(QImageIO* iio) { QImage image; struct jpeg_decompress_struct cinfo; struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(iio); struct my_error_mgr jerr; jpeg_create_decompress(&cinfo); cinfo.src = iod_src; cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = my_error_exit; if (!setjmp(jerr.setjmp_buffer)) { #if defined(_OS_UNIXWARE7_) (void) jpeg_read_header(&cinfo, B_TRUE); #else (void) jpeg_read_header(&cinfo, TRUE); #endif (void) jpeg_start_decompress(&cinfo); if ( cinfo.output_components == 3 || cinfo.output_components == 4) { image.create( cinfo.output_width, cinfo.output_height, 32 ); } else if ( cinfo.output_components == 1 ) { image.create( cinfo.output_width, cinfo.output_height, 8, 256 ); for (int i=0; i<256; i++) image.setColor(i, qRgb(i,i,i)); } else { // Unsupported format } if (!image.isNull()) { uchar** lines = image.jumpTable(); while (cinfo.output_scanline < cinfo.output_height) (void) jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline, cinfo.output_height); (void) jpeg_finish_decompress(&cinfo); } if ( cinfo.output_components == 3 ) { // Expand 24->32 bpp. for (uint j=0; j<cinfo.output_height; j++) { uchar *in = image.scanLine(j) + cinfo.output_width * 3; QRgb *out = (QRgb*)image.scanLine(j); for (uint i=cinfo.output_width; i--; ) { in-=3; out[i] = qRgb(in[0], in[1], in[2]); } } } iio->setImage(image); iio->setStatus(0); } jpeg_destroy_decompress(&cinfo); delete iod_src; }
void QPaintEngineEx::drawImage(const QPointF &pos, const QImage &image) { drawImage(QRectF(pos, image.size()), image, image.rect()); }
bool ImageResize::imageResize(const EmailSettingsContainer& settings, const KUrl& orgUrl, const QString& destName, QString& err) { EmailSettingsContainer emailSettings = settings; QFileInfo fi(orgUrl.path()); if (!fi.exists() || !fi.isReadable()) { err = i18n("Error in opening input file"); return false; } QFileInfo tmp(emailSettings.tempPath); if (!tmp.exists() || !tmp.isWritable()) { err = i18n("Error in opening temporary folder"); return false; } QImage img; // Check if RAW file. #if KDCRAW_VERSION < 0x000400 QString rawFilesExt(KDcrawIface::DcrawBinary::instance()->rawFiles()); #else QString rawFilesExt(KDcrawIface::KDcraw::rawFiles()); #endif if (rawFilesExt.toUpper().contains( fi.suffix().toUpper() )) KDcrawIface::KDcraw::loadDcrawPreview(img, orgUrl.path()); else img.load(orgUrl.path()); int sizeFactor = emailSettings.size(); if ( !img.isNull() ) { int w = img.width(); int h = img.height(); if( w > sizeFactor || h > sizeFactor ) { if( w > h ) { h = (int)( (double)( h * sizeFactor ) / w ); if ( h == 0 ) h = 1; w = sizeFactor; Q_ASSERT( h <= sizeFactor ); } else { w = (int)( (double)( w * sizeFactor ) / h ); if ( w == 0 ) w = 1; h = sizeFactor; Q_ASSERT( w <= sizeFactor ); } const QImage scaledImg(img.scaled(w, h)); if ( scaledImg.width() != w || scaledImg.height() != h ) { err = i18n("Cannot resizing image. Aborting."); return false; } img = scaledImg; } QString destPath = emailSettings.tempPath + destName; KExiv2Iface::KExiv2 meta; meta.load(orgUrl.path()); meta.setImageProgramId(QString("Kipi-plugins"), QString(kipiplugins_version)); meta.setImageDimensions(img.size()); if (emailSettings.format() == QString("JPEG")) { if ( !img.save(destPath, emailSettings.format().toLatin1(), emailSettings.imageCompression) ) { err = i18n("Cannot save resized image (JPEG). Aborting."); return false; } else { meta.save(destPath); } } else if (emailSettings.format() == QString("PNG")) { QByteArray data((const char*)img.bits(), img.numBytes()); KIPIPlugins::KPWriteImage wImageIface; wImageIface.setImageData(data, img.width(), img.height(), false, true, QByteArray(), meta); if ( !wImageIface.write2PNG(destPath) ) { err = i18n("Cannot save resized image (PNG). Aborting."); return false; } } return true; } return false; }
void imageSize(QImage_ *image, int *width, int *height) { QImage *qimage = reinterpret_cast<QImage *>(image); *width = qimage->width(); *height = qimage->height(); }
bool PiwigoTalker::addPhoto(int albumId, const QString& mediaPath, bool rescale, int maxWidth, int maxHeight, int quality) { m_job = 0; m_state = GE_CHECKPHOTOEXIST; m_talker_buffer.resize(0); m_path = mediaPath; // By default, m_path contains the original file m_tmpPath = QStringLiteral(""); // By default, no temporary file (except with rescaling) m_albumId = albumId; m_md5sum = computeMD5Sum(mediaPath); qCDebug(KIPIPLUGINS_LOG) << mediaPath << " " << m_md5sum.toHex(); if (mediaPath.endsWith(QStringLiteral(".mp4")) || mediaPath.endsWith(QStringLiteral(".MP4")) || mediaPath.endsWith(QStringLiteral(".ogg")) || mediaPath.endsWith(QStringLiteral(".OGG")) || mediaPath.endsWith(QStringLiteral(".webm")) || mediaPath.endsWith(QStringLiteral(".WEBM"))) { // Video management // Nothing to do } else { // Image management QImage image; if (m_iface) { QPointer<RawProcessor> rawdec = m_iface->createRawProcessor(); // check if its a RAW file. if (rawdec && rawdec->isRawFile(QUrl::fromLocalFile(mediaPath))) { rawdec->loadRawPreview(QUrl::fromLocalFile(mediaPath), image); } } if (image.isNull()) { image.load(mediaPath); } if (image.isNull()) { // Invalid image return false; } if (!rescale) { qCDebug(KIPIPLUGINS_LOG) << "Upload the original version: " << m_path; } else { // Rescale the image if (image.width() > maxWidth || image.height() > maxHeight) { image = image.scaled(maxWidth, maxHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); } m_path = m_tmpPath = makeTemporaryDir("kipi-piwigo").filePath(QUrl::fromLocalFile(mediaPath).fileName()); image.save(m_path, "JPEG", quality); qCDebug(KIPIPLUGINS_LOG) << "Upload a resized version: " << m_path ; // Restore all metadata with EXIF // in the resized version if (m_iface) { QPointer<MetadataProcessor> meta = m_iface->createMetadataProcessor(); if (meta && meta->load(QUrl::fromLocalFile(mediaPath))) { meta->setImageProgramId(QStringLiteral("Kipi-plugins"), kipipluginsVersion()); meta->setImageDimensions(image.size()); meta->save(QUrl::fromLocalFile(m_path)); } else { qCDebug(KIPIPLUGINS_LOG) << "Image " << mediaPath << " has no exif data"; } } } } // Metadata management // Complete name and comment for summary sending QFileInfo fi(mediaPath); m_title = fi.completeBaseName(); m_comment = QStringLiteral(""); m_author = QStringLiteral(""); m_date = fi.created(); // Look in the Kipi host database KPImageInfo info(QUrl::fromLocalFile(mediaPath)); if (info.hasTitle() && !info.title().isEmpty()) m_title = info.title(); if (info.hasDescription() && !info.description().isEmpty()) m_comment = info.description(); if (info.hasCreators() && !info.creators().isEmpty()) m_author = info.creators().join(QStringLiteral(" / ")); if (info.hasDate()) m_date = info.date(); qCDebug(KIPIPLUGINS_LOG) << "Title: " << m_title; qCDebug(KIPIPLUGINS_LOG) << "Comment: " << m_comment; qCDebug(KIPIPLUGINS_LOG) << "Author: " << m_author; qCDebug(KIPIPLUGINS_LOG) << "Date: " << m_date; QStringList qsl; qsl.append(QLatin1String("method=pwg.images.exist")); qsl.append(QLatin1String("md5sum_list=") + QString::fromLatin1(m_md5sum.toHex())); QString dataParameters = qsl.join(QLatin1String("&")); QByteArray buffer; buffer.append(dataParameters.toUtf8()); m_job = KIO::http_post(m_url, buffer, KIO::HideProgressInfo); m_job->addMetaData(QStringLiteral("content-type"), QStringLiteral("Content-Type: application/x-www-form-urlencoded")); m_job->addMetaData(QStringLiteral("customHTTPHeader"), QStringLiteral("Authorization: ") + s_authToken); emit signalProgressInfo( i18n("Check if %1 already exists", QUrl(mediaPath).fileName()) ); connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, SLOT(slotTalkerData(KIO::Job*,QByteArray))); connect(m_job, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*))); emit signalBusy(true); return true; }
QPixmap TabBar::makePixmapForDrag(int index) { std::vector< std::pair<QString,QIcon > > tabs; for (int i = 0; i < count(); ++i) { tabs.push_back(std::make_pair(tabText(i),tabIcon(i))); } //remove all tabs while (count() > 0) { removeTab(0); } ///insert just the tab we want to screen shot addTab(tabs[index].second, tabs[index].first); QPixmap currentTabPixmap = Gui::screenShot(_tabWidget->tabAt(index)); #if QT_VERSION < 0x050000 QPixmap tabBarPixmap = QPixmap::grabWidget(this); #else QPixmap tabBarPixmap = grab(); #endif ///re-insert all the tabs into the tab bar removeTab(0); for (U32 i = 0; i < tabs.size(); ++i) { addTab(tabs[i].second, tabs[i].first); } QImage tabBarImg = tabBarPixmap.toImage(); QImage currentTabImg = currentTabPixmap.toImage(); //now we just put together the 2 pixmaps and set it with mid transparancy QImage ret(currentTabImg.width(),currentTabImg.height() + tabBarImg.height(),QImage::Format_ARGB32_Premultiplied); for (int y = 0; y < tabBarImg.height(); ++y) { QRgb* src_pixels = reinterpret_cast<QRgb*>(tabBarImg.scanLine(y)); for (int x = 0; x < ret.width(); ++x) { if (x < tabBarImg.width()) { QRgb pix = src_pixels[x]; ret.setPixel(x, y, qRgba(qRed(pix), qGreen(pix), qBlue(pix), 255)); } else { ret.setPixel(x, y, qRgba(0, 0, 0, 128)); } } } for (int y = 0; y < currentTabImg.height(); ++y) { QRgb* src_pixels = reinterpret_cast<QRgb*>(currentTabImg.scanLine(y)); for (int x = 0; x < ret.width(); ++x) { QRgb pix = src_pixels[x]; ret.setPixel(x, y + tabBarImg.height(), qRgba(qRed(pix), qGreen(pix), qBlue(pix), 255)); } } return QPixmap::fromImage(ret); }
QDBusArgument& operator<< (QDBusArgument& arg, const DBusNotifyImageData &data) { if (data.image.isNull()) { // Sometimes this gets called with a null QImage for no obvious reason. // - There is one reason: Qt calls this method at first time to research it's structure arg.beginStructure(); arg << 0 << 0 << 0 << false << 0 << 0 << QByteArray(); arg.endStructure(); return arg; } QImage scaled = data.image.scaledToHeight(qMin(100, qMin(data.image.height(), data.image.width())), Qt::SmoothTransformation).toImage(); QImage i = scaled.convertToFormat(QImage::Format_ARGB32).rgbSwapped(); arg.beginStructure(); arg << i.width(); arg << i.height(); arg << i.bytesPerLine(); arg << i.hasAlphaChannel(); int channels = i.isGrayscale() ? 1 : (i.hasAlphaChannel() ? 4 : 3); arg << i.depth() / channels; arg << channels; arg << QByteArray(reinterpret_cast<const char*>(i.bits()), i.numBytes()); arg.endStructure(); return arg; }
void CQOpenGL::GlSaveScreenShot(QString FilePath) { QImage Image; Image = grabFrameBuffer(); Image.save(FilePath, 0, 95); }
void Controller::ComputeSteerableViewMap() { #if 0 //soc if ((!_Canvas) || (!_ViewMap)) return; // Build 4 nodes containing the edges in the 4 directions NodeGroup *ng[Canvas::NB_STEERABLE_VIEWMAP]; unsigned i; real c = 32.0f/255.0f; // see SteerableViewMap::readSteerableViewMapPixel() for information about this 32. for (i = 0; i < Canvas::NB_STEERABLE_VIEWMAP; ++i) { ng[i] = new NodeGroup; } NodeShape *completeNS = new NodeShape; completeNS->material().setDiffuse(c,c,c,1); ng[Canvas::NB_STEERABLE_VIEWMAP-1]->AddChild(completeNS); SteerableViewMap * svm = _Canvas->getSteerableViewMap(); svm->Reset(); ViewMap::fedges_container& fedges = _ViewMap->FEdges(); LineRep * fRep; NodeShape *ns; for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) { if ((*f)->viewedge()->qi() != 0) continue; fRep = new LineRep((*f)->vertexA()->point2d(), (*f)->vertexB()->point2d()); completeNS->AddRep(fRep); // add to the complete map anyway double *oweights = svm->AddFEdge(*f); for (i = 0; i < (Canvas::NB_STEERABLE_VIEWMAP - 1); ++i) { ns = new NodeShape; double wc = oweights[i]*c; if (oweights[i] == 0) continue; ns->material().setDiffuse(wc, wc, wc, 1); ns->AddRep(fRep); ng[i]->AddChild(ns); } } GrayImage *img[Canvas::NB_STEERABLE_VIEWMAP]; //#ifdef WIN32 QGLBasicWidget offscreenBuffer(_pView, "SteerableViewMap", _pView->width(), _pView->height()); QPixmap pm; QImage qimg; for (i = 0; i < Canvas::NB_STEERABLE_VIEWMAP; ++i) { offscreenBuffer.AddNode(ng[i]); #if 0 img[i] = new GrayImage(_pView->width(), _pView->height()); offscreenBuffer.readPixels(0,0,_pView->width(), _pView->height(), img[i]->getArray()); #endif pm = offscreenBuffer.renderPixmap(_pView->width(), _pView->height()); if (pm.isNull()) { if (G.debug & G_DEBUG_FREESTYLE) { cout << "BuildViewMap Warning: couldn't render the steerable ViewMap" << endl; } } //pm.save(QString("steerable") + QString::number(i) + QString(".bmp"), "BMP"); // FIXME!! Lost of time ! qimg = pm.toImage(); // FIXME !! again! img[i] = new GrayImage(_pView->width(), _pView->height()); for (unsigned int y = 0; y < img[i]->height(); ++y) { for (unsigned int x = 0; x < img[i]->width(); ++x) { //img[i]->setPixel(x, y, (float)qGray(qimg.pixel(x, y)) / 255.0f); img[i]->setPixel(x, y, (float)qGray(qimg.pixel(x, y))); //float c = qGray(qimg.pixel(x, y)); //img[i]->setPixel(x, y, qGray(qimg.pixel(x, y))); } } offscreenBuffer.DetachNode(ng[i]); ng[i]->destroy(); delete ng[i]; // check #if 0 qimg = QImage(_pView->width(), _pView->height(), 32); for (unsigned int y = 0; y < img[i]->height(); ++y) { for (unsigned int x = 0; x < img[i]->width(); ++x) { float v = img[i]->pixel(x, y); qimg.setPixel(x, y, qRgb(v, v, v)); } } qimg.save(QString("newsteerable") + QString::number(i) + QString(".bmp"), "BMP"); #endif } svm->buildImagesPyramids(img, false, 0, 1.0f); #endif }
QImage setAlphaMask(QImage image, QImage mask) { if(mask.isNull()) return image; if(image.isNull()) return image; QImage target = image; QImage newmask = mask; if(target.size()!= newmask.size()) { newmask = newmask.copy(0,0, target.width(), target.height()); } newmask.invertPixels(); target.setAlphaChannel(newmask); return target; }
const unsigned char *imageConstBits(QImage_ *image) { QImage *qimage = reinterpret_cast<QImage *>(image); return qimage->constBits(); }
QImage ImageProviderThumbnail::getThumbnailImage(QByteArray filename) { QString typeCache = (settings->thumbnailCacheFile ? "files" : "db"); bool cacheEnabled = settings->thumbnailCache; if(settings->thumbnailCache && !settings->thumbnailCacheFile) setupDbWhenNotYetDone(); // Create the md5 hash for the thumbnail file QByteArray path = "file://" + filename; QByteArray md5 = QCryptographicHash::hash(path,QCryptographicHash::Md5).toHex(); // Prepare the return QImage QImage p; // We always opt for the 256px resolution for the thumbnails, // as then we don't have to re-create thumbnails depending on change in settings int ts = 256; // If files in XDG_CACHE_HOME/thumbnails/ shall be used, then do use them if(typeCache == "files" && cacheEnabled) { // If there exists a thumbnail of the current file already if(QFile(ConfigFiles::GENERIC_CACHE_DIR() + "/thumbnails/large/" + md5 + ".png").exists()) { if(qgetenv("PHOTOQT_DEBUG") == "yes") LOG << CURDATE << "ImageProviderThumbnail: Found cached thumbnail (file cache): " << QFileInfo(filename).fileName().toStdString() << NL; p.load(ConfigFiles::GENERIC_CACHE_DIR() + "/thumbnails/large/" + md5 + ".png"); uint mtime = p.text("Thumb::MTime").trimmed().toInt(); // Use image if it's up-to-date if(QFileInfo(filename).lastModified().toTime_t() == mtime) return p; else if(qgetenv("PHOTOQT_DEBUG") == "yes") LOG << CURDATE << "ImageProviderThumbnail: Image was modified since thumbnail creation, not using cached thumbnail: " << QFileInfo(filename).fileName().toStdString() << NL; } // otherwise use the database } else if(cacheEnabled) { needToReCreatedDbThumbnail = false; // Query database QSqlQuery query(db); query.prepare("SELECT thumbnail,filelastmod FROM Thumbnails WHERE filepath=:fpath"); query.bindValue(":fpath",filename); query.exec(); // Check for found value if(query.next()) { if(qgetenv("PHOTOQT_DEBUG") == "yes") LOG << CURDATE << "ImageProviderThumbnail: Found cached thumbnail (db cache): " << QFileInfo(filename).fileName().toStdString() << NL; // Check if updated if(query.value(query.record().indexOf("filelastmod")).toUInt() == QFileInfo(filename).lastModified().toTime_t()) { // If current thumbnail -> load it QByteArray b; b = query.value(query.record().indexOf("thumbnail")).toByteArray(); p.loadFromData(b); // Cleaning up query.clear(); // Return image return p; // The original image has been changed -> need to recreate thumbnail image } else { if(qgetenv("PHOTOQT_DEBUG") == "yes") LOG << CURDATE << "ImageProviderThumbnail: Image was modified since thumbnail creation, not using cached thumbnail: " << QFileInfo(filename).fileName().toStdString() << NL; needToReCreatedDbThumbnail = true; } } // Cleaning up query.clear(); } // If file wasn't loaded from file or database, then it doesn't exist yet (or isn't up-to-date anymore) and we have to create it // We create a temporary pointer, so that we can delete it properly afterwards QSize *tmp = new QSize(ts,ts); p = imageproviderfull->requestImage(filename.toPercentEncoding(),tmp,QSize(ts,ts)); delete tmp; // Only if the image itself is smaller than the requested thumbnail size are both dimensions less than (strictly) than ts -> no caching if((p.width() < ts && p.height() < ts) || p.text("error") == "error") { if(qgetenv("PHOTOQT_DEBUG") == "yes") LOG << CURDATE << "ImageProviderThumbnail: Image is smaller than potential thumbnail, no need to cache: " << QFileInfo(filename).fileName().toStdString() << NL; return p; } // Create file cache thumbnail if(typeCache == "files" && cacheEnabled) { // If the file itself wasn't read from the thumbnails folder, is not a temporary file, and if the original file isn't at thumbnail size itself if(!filename.startsWith(QString(ConfigFiles::GENERIC_CACHE_DIR() + "/thumbnails").toUtf8()) && !filename.startsWith(QDir::tempPath().toUtf8())) { // Set some required (and additional) meta information p.setText("Thumb::URI", QString("file://%1").arg(QString(filename))); p.setText("Thumb::MTime", QString("%1").arg(QFileInfo(filename).lastModified().toTime_t())); QString mime = mimedb.mimeTypeForFile(filename, QMimeDatabase::MatchContent).name(); // this is the default mime type if no mime type is available or file cannot be found if(mime != "application/octet-stream") p.setText("Thumb::Mimetype", mime); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) p.setText("Thumb::Size", QString("%1").arg(p.sizeInBytes())); #else QFileInfo info(filename); p.setText("Thumb::Size", QString("%1").arg(info.size())); #endif // If the file does already exist, then the image has likely been updated -> delete old thumbnail image if(QFile(ConfigFiles::GENERIC_CACHE_DIR() + "/thumbnails/large/" + md5 + ".png").exists()) QFile(ConfigFiles::GENERIC_CACHE_DIR() + "/thumbnails/large/" + md5 + ".png").remove(); // And save new thumbnail image if(!p.save(ConfigFiles::GENERIC_CACHE_DIR() + "/thumbnails/large/" + md5 + ".png")) LOG << CURDATE << "ImageProviderThumbnail: ERROR creating new thumbnail file: " << QFileInfo(filename).fileName().toStdString() << NL; else if(qgetenv("PHOTOQT_DEBUG") == "yes") LOG << CURDATE << "ImageProviderThumbnail: Successfully cached thumbnail (file cache): " << QFileInfo(filename).fileName().toStdString() << NL; } // if not file caching -> db caching } else if(cacheEnabled) { // make sure transaction is started if(!dbTransactionStarted) { if(!db.transaction()) LOG << CURDATE << "ImageProviderThumbnail: ERROR: Cannot start db transaction" << NL; dbTransactionStarted = true; } QSqlQuery query2(db); // convert image to bytearray QByteArray b; QBuffer buf(&b); buf.open(QIODevice::WriteOnly); // Always use png format p.save(&buf,"PNG"); // If it was once created, i.e. if the file changed (i.e. if last mod date changed), then we have to update it if(needToReCreatedDbThumbnail) query2.prepare("UPDATE Thumbnails SET filepath=:path,thumbnail=:thb,filelastmod=:mod,thumbcreated=:crt WHERE filepath=:path"); else query2.prepare("INSERT INTO Thumbnails(filepath,thumbnail,filelastmod,thumbcreated) VALUES(:path,:thb,:mod,:crt)"); // bind the thumbnail properties query2.bindValue(":path",filename); query2.bindValue(":thb",b); query2.bindValue(":mod",QFileInfo(filename).lastModified().toTime_t()); query2.bindValue(":crt",QDateTime::currentMSecsSinceEpoch()); query2.exec(); if(query2.lastError().text().trimmed().length()) LOG << CURDATE << "ImageProviderThumbnail: ERROR [" << QString(filename).toStdString() << "]: " << query2.lastError().text().trimmed().toStdString() << NL; else if(qgetenv("PHOTOQT_DEBUG") == "yes") LOG << CURDATE << "ImageProviderThumbnail: Successfully cached thumbnail (db cache): " << QFileInfo(filename).fileName().toStdString() << NL; // cleaning up query2.clear(); } // aaaaand done! return p; }
QImage VectorscopeGenerator::calculateVectorscope(const QSize &vectorscopeSize, const QImage &image, const float &gain, const VectorscopeGenerator::PaintMode &paintMode, const VectorscopeGenerator::ColorSpace &colorSpace, const bool &, const uint &accelFactor) const { if (vectorscopeSize.width() <= 0 || vectorscopeSize.height() <= 0 || image.width() <= 0 || image.height() <= 0) { // Invalid size return QImage(); } // Prepare the vectorscope data const int cw = (vectorscopeSize.width() < vectorscopeSize.height()) ? vectorscopeSize.width() : vectorscopeSize.height(); QImage scope = QImage(cw, cw, QImage::Format_ARGB32); scope.fill(qRgba(0,0,0,0)); const uchar *bits = image.bits(); int r,g,b; double dy, dr, dg, db, dmax; double /*y,*/ u, v; QPoint pt; QRgb px; const int stepsize = 4 * accelFactor; // Just an average for the number of image pixels per scope pixel. // NOTE: byteCount() has to be replaced by (img.bytesPerLine()*img.height()) for Qt 4.5 to compile, see: http://doc.trolltech.org/4.6/qimage.html#bytesPerLine double avgPxPerPx = (double) 4*(image.bytesPerLine()*image.height())/scope.size().width()/scope.size().height()/accelFactor; for (int i = 0; i < (image.bytesPerLine()*image.height()); i+= stepsize) { QRgb *col = (QRgb *) bits; r = qRed(*col); g = qGreen(*col); b = qBlue(*col); switch (colorSpace) { case VectorscopeGenerator::ColorSpace_YUV: // y = (double) 0.001173 * r +0.002302 * g +0.0004471* b; u = (double) -0.0005781* r -0.001135 * g +0.001713 * b; v = (double) 0.002411 * r -0.002019 * g -0.0003921* b; break; case VectorscopeGenerator::ColorSpace_YPbPr: default: // y = (double) 0.001173 * r +0.002302 * g +0.0004471* b; u = (double) -0.0006671* r -0.001299 * g +0.0019608* b; v = (double) 0.001961 * r -0.001642 * g -0.0003189* b; break; } pt = mapToCircle(vectorscopeSize, QPointF(SCALING*gain*u, SCALING*gain*v)); if (pt.x() >= scope.width() || pt.x() < 0 || pt.y() >= scope.height() || pt.y() < 0) { // Point lies outside (because of scaling), don't plot it } else { // Draw the pixel using the chosen draw mode. switch (paintMode) { case PaintMode_YUV: // see yuvColorWheel dy = 128; // Default Y value. Lower = darker. // Calculate the RGB values from YUV/YPbPr switch (colorSpace) { case VectorscopeGenerator::ColorSpace_YUV: dr = dy + 290.8*v; dg = dy - 100.6*u - 148*v; db = dy + 517.2*u; break; case VectorscopeGenerator::ColorSpace_YPbPr: default: dr = dy + 357.5*v; dg = dy - 87.75*u - 182*v; db = dy + 451.9*u; break; } if (dr < 0) dr = 0; if (dg < 0) dg = 0; if (db < 0) db = 0; if (dr > 255) dr = 255; if (dg > 255) dg = 255; if (db > 255) db = 255; scope.setPixel(pt, qRgba(dr, dg, db, 255)); break; case PaintMode_Chroma: dy = 200; // Default Y value. Lower = darker. // Calculate the RGB values from YUV/YPbPr switch (colorSpace) { case VectorscopeGenerator::ColorSpace_YUV: dr = dy + 290.8*v; dg = dy - 100.6*u - 148*v; db = dy + 517.2*u; break; case VectorscopeGenerator::ColorSpace_YPbPr: default: dr = dy + 357.5*v; dg = dy - 87.75*u - 182*v; db = dy + 451.9*u; break; } // Scale the RGB values back to max 255 dmax = dr; if (dg > dmax) dmax = dg; if (db > dmax) dmax = db; dmax = 255/dmax; dr *= dmax; dg *= dmax; db *= dmax; scope.setPixel(pt, qRgba(dr, dg, db, 255)); break; case PaintMode_Original: scope.setPixel(pt, *col); break; case PaintMode_Green: px = scope.pixel(pt); scope.setPixel(pt, qRgba(qRed(px)+(255-qRed(px))/(3*avgPxPerPx), qGreen(px)+20*(255-qGreen(px))/(avgPxPerPx), qBlue(px)+(255-qBlue(px))/(avgPxPerPx), qAlpha(px)+(255-qAlpha(px))/(avgPxPerPx))); break; case PaintMode_Green2: px = scope.pixel(pt); scope.setPixel(pt, qRgba(qRed(px)+ceil((255-(float)qRed(px))/(4*avgPxPerPx)), 255, qBlue(px)+ceil((255-(float)qBlue(px))/(avgPxPerPx)), qAlpha(px)+ceil((255-(float)qAlpha(px))/(avgPxPerPx)))); break; case PaintMode_Black: px = scope.pixel(pt); scope.setPixel(pt, qRgba(0,0,0, qAlpha(px)+(255-qAlpha(px))/20)); break; } } bits += stepsize; } return scope; }
QImage* LH_QImage::getPlaceholder() { QImage* image = new QImage(); image->loadFromData(_logo_blob_d.data, _logo_blob_d.len); return image; }
void QBlittablePixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags) { m_alpha = image.hasAlphaChannel(); resize(image.width(),image.height()); markRasterOverlay(QRect(0,0,w,h)); QImage *thisImg = buffer(); QImage correctFormatPic = image; if (correctFormatPic.format() != thisImg->format()) correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags); uchar *mem = thisImg->bits(); const uchar *bits = correctFormatPic.bits(); int bytesCopied = 0; while (bytesCopied < correctFormatPic.byteCount()) { memcpy(mem,bits,correctFormatPic.bytesPerLine()); mem += thisImg->bytesPerLine(); bits += correctFormatPic.bytesPerLine(); bytesCopied+=correctFormatPic.bytesPerLine(); } }
void LEDButton::paintEvent(QPaintEvent *) { QPainter paint; QColor color; QBrush brush; QPen pen; // First of all we want to know what area should be updated // Initialize coordinates, width, and height of the LED int width = this->width(); // Make sure the LED is round! if (width > this->height()) width = this->height(); width -= 2; // leave one pixel border if (width < 0) width = 0; QPixmap *tmpMap = 0; if (led_state) { if (d->on_map) { if (d->on_map->size() == size()) { paint.begin(this); paint.drawPixmap(0, 0, *d->on_map); paint.end(); return; } else { delete d->on_map; d->on_map = 0; } } } else { if (d->off_map) { if (d->off_map->size() == size()) { paint.begin(this); paint.drawPixmap(0, 0, *d->off_map); paint.end(); return; } else { delete d->off_map; d->off_map = 0; } } } int scale = 1; width *= scale; tmpMap = new QPixmap(width, width); tmpMap->fill(palette().background().color()); paint.begin(tmpMap); paint.setRenderHint(QPainter::Antialiasing, true); // Set the color of the LED according to given parameters color = (led_state) ? led_color : d->offcolor; // Set the brush to SolidPattern, this fills the entire area // of the ellipse which is drawn first brush.setStyle(Qt::SolidPattern); brush.setColor(color); paint.setBrush(brush); // Draws a "flat" LED with the given color: paint.drawEllipse( scale, scale, width - scale*2, width - scale*2 ); // Draw the bright light spot of the LED now, using modified "old" // painter routine taken from KDEUI´s LEDButton widget: // Setting the new width of the pen is essential to avoid "pixelized" // shadow like it can be observed with the old LED code pen.setWidth( 2 * scale ); // shrink the light on the LED to a size about 2/3 of the complete LED int pos = width/5 + 1; int light_width = width; light_width *= 2; light_width /= 3; // Calculate the LED´s "light factor": int light_quote = (130*2/(light_width?light_width:1))+100; // Now draw the bright spot on the LED: while (light_width) { color = color.light( light_quote ); // make color lighter pen.setColor( color ); // set color as pen color paint.setPen( pen ); // select the pen for drawing paint.drawEllipse( pos, pos, light_width, light_width ); // draw the ellipse (circle) light_width--; if (!light_width) break; paint.drawEllipse( pos, pos, light_width, light_width ); light_width--; if (!light_width) break; paint.drawEllipse( pos, pos, light_width, light_width ); pos++; light_width--; } // Drawing of bright spot finished, now draw a thin border // around the LED which resembles a shadow with light coming // from the upper left. // pen.setWidth( 2 * scale + 1 ); // ### shouldn't this value be smaller for smaller LEDs? pen.setWidth(2 * scale); brush.setStyle(Qt::NoBrush); paint.setBrush(brush); // This avoids filling of the ellipse // Set the initial color value to colorGroup().light() (bright) and start // drawing the shadow border at 45° (45*16 = 720). int angle = -720; color = palette().light().color(); for (int arc = 120; arc < 2880; arc += 240) { pen.setColor(color); paint.setPen(pen); int w = width - pen.width()/2 - scale + 1; paint.drawArc(pen.width()/2 + 1, pen.width()/2 + 1, w - 2, w - 2, angle + arc, 240); paint.drawArc(pen.width()/2 + 1, pen.width()/2 + 1, w - 2, w - 2, angle - arc, 240); color = color.dark(110); //FIXME: this should somehow use the contrast value } // end for ( angle = 720; angle < 6480; angle += 160 ) paint.end(); // // painting done QPixmap *&dest = led_state ? d->on_map : d->off_map; if (scale > 1) { QImage i = tmpMap->toImage(); width /= scale; delete tmpMap; dest = new QPixmap(QPixmap::fromImage (i.scaled(width, width, Qt::KeepAspectRatio, Qt::SmoothTransformation))); } else { dest = tmpMap; } paint.begin(this); paint.drawPixmap(0, 0, *dest); paint.end(); }
void game_list_frame::Refresh(bool fromDrive) { if (fromDrive) { // Load PSF m_game_data.clear(); const std::string& game_path = Emu.GetGameDir(); for (const auto& entry : fs::dir(Emu.GetGameDir())) { if (!entry.is_directory) { continue; } const std::string& dir = game_path + entry.name; const std::string& sfb = dir + "/PS3_DISC.SFB"; const std::string& sfo = dir + (fs::is_file(sfb) ? "/PS3_GAME/PARAM.SFO" : "/PARAM.SFO"); const fs::file sfo_file(sfo); if (!sfo_file) { continue; } const auto& psf = psf::load_object(sfo_file); GameInfo game; game.root = entry.name; game.serial = psf::get_string(psf, "TITLE_ID", ""); game.name = psf::get_string(psf, "TITLE", "unknown"); game.app_ver = psf::get_string(psf, "APP_VER", "unknown"); game.category = psf::get_string(psf, "CATEGORY", "unknown"); game.fw = psf::get_string(psf, "PS3_SYSTEM_VER", "unknown"); game.parental_lvl = psf::get_integer(psf, "PARENTAL_LEVEL"); game.resolution = psf::get_integer(psf, "RESOLUTION"); game.sound_format = psf::get_integer(psf, "SOUND_FORMAT"); if (game.category == "HG") { game.category = sstr(category::hdd_Game); game.icon_path = dir + "/ICON0.PNG"; } else if (game.category == "DG") { game.category = sstr(category::disc_Game); game.icon_path = dir + "/PS3_GAME/ICON0.PNG"; } else if (game.category == "HM") { game.category = sstr(category::home); game.icon_path = dir + "/ICON0.PNG"; } else if (game.category == "AV") { game.category = sstr(category::audio_Video); game.icon_path = dir + "/ICON0.PNG"; } else if (game.category == "GD") { game.category = sstr(category::game_Data); game.icon_path = dir + "/ICON0.PNG"; } else if (game.category == "unknown") { game.category = sstr(category::unknown); } // Load Image QImage img; QPixmap pxmap; if (!game.icon_path.empty() && img.load(qstr(game.icon_path))) { QImage scaled = img.scaled(m_Icon_Size, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation); pxmap = QPixmap::fromImage(scaled); } else { img = QImage(m_Icon_Size, QImage::Format_ARGB32); QString abspath = QDir(qstr(game.icon_path)).absolutePath(); LOG_ERROR(HLE, "Count not load image from path %s", sstr(abspath)); img.fill(QColor(0, 0, 0, 0)); pxmap = QPixmap::fromImage(img); } m_game_data.push_back({ game, img, pxmap }); } auto op = [](const GUI_GameInfo& game1, const GUI_GameInfo& game2) { return game1.info.name < game2.info.name; }; // Sort by name at the very least. std::sort(m_game_data.begin(), m_game_data.end(), op); } // Fill Game List / Game Grid if (m_isListLayout) { int row = PopulateGameList(); FilterData(); gameList->selectRow(row); gameList->sortByColumn(m_sortColumn, m_colSortOrder); gameList->verticalHeader()->setMinimumSectionSize(m_Icon_Size.height()); gameList->verticalHeader()->setMaximumSectionSize(m_Icon_Size.height()); gameList->resizeRowsToContents(); gameList->resizeColumnToContents(0); gameList->scrollTo(gameList->currentIndex()); } else { if (m_Icon_Size.width() > 0 && m_Icon_Size.height() > 0) { m_games_per_row = width() / (m_Icon_Size.width() + m_Icon_Size.width() * m_xgrid->getMarginFactor() * 2); } else { m_games_per_row = 0; } PopulateGameGrid(m_games_per_row, m_Icon_Size); connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); m_Central_Widget->addWidget(m_xgrid); m_Central_Widget->setCurrentWidget(m_xgrid); m_xgrid->scrollTo(m_xgrid->currentIndex()); } }
static void set_text(const QImage &image, png_structp png_ptr, png_infop info_ptr, const QString &description) { QMap<QString, QString> text; foreach (const QString &key, image.textKeys()) { if (!key.isEmpty()) text.insert(key, image.text(key)); } foreach (const QString &pair, description.split(QLatin1String("\n\n"))) { int index = pair.indexOf(QLatin1Char(':')); if (index >= 0 && pair.indexOf(QLatin1Char(' ')) < index) { QString s = pair.simplified(); if (!s.isEmpty()) text.insert(QLatin1String("Description"), s); } else { QString key = pair.left(index); if (!key.simplified().isEmpty()) text.insert(key, pair.mid(index + 2).simplified()); } } if (text.isEmpty()) return; png_textp text_ptr = new png_text[text.size()]; memset(text_ptr, 0, text.size() * sizeof(png_text)); QMap<QString, QString>::ConstIterator it = text.constBegin(); int i = 0; while (it != text.constEnd()) { text_ptr[i].key = qstrdup(it.key().left(79).toLatin1().constData()); bool noCompress = (it.value().length() < 40); #ifdef PNG_iTXt_SUPPORTED bool needsItxt = false; foreach(const QChar c, it.value()) { uchar ch = c.cell(); if (c.row() || (ch < 0x20 && ch != '\n') || (ch > 0x7e && ch < 0xa0)) { needsItxt = true; break; } } if (needsItxt) { text_ptr[i].compression = noCompress ? PNG_ITXT_COMPRESSION_NONE : PNG_ITXT_COMPRESSION_zTXt; QByteArray value = it.value().toUtf8(); text_ptr[i].text = qstrdup(value.constData()); text_ptr[i].itxt_length = value.size(); text_ptr[i].lang = const_cast<char*>("UTF-8"); text_ptr[i].lang_key = qstrdup(it.key().toUtf8().constData()); } else #endif { text_ptr[i].compression = noCompress ? PNG_TEXT_COMPRESSION_NONE : PNG_TEXT_COMPRESSION_zTXt; QByteArray value = it.value().toLatin1(); text_ptr[i].text = qstrdup(value.constData()); text_ptr[i].text_length = value.size(); } ++i; ++it; } png_set_text(png_ptr, info_ptr, text_ptr, i); for (i = 0; i < text.size(); ++i) { delete [] text_ptr[i].key; delete [] text_ptr[i].text; #ifdef PNG_iTXt_SUPPORTED delete [] text_ptr[i].lang_key; #endif } delete [] text_ptr; }
std::vector<QPoint> floodFill(QImage *img, const QPoint &pos, const QRgb &newColor) { QImage image = img->copy(); std::vector<QPoint> modified; int x = pos.x(), y = pos.y(); const QRgb oldColor = image.pixel(x, y); std::vector<fillpixelinfo> stack; int l, x1, x2, dy; if ((x >= 0) && (x < image.width()) && (y >= 0) && (y < image.height())) { if (oldColor == newColor) { return modified; } PUSH(y, x, x, 1); PUSH(y + 1, x, x, -1); while (!stack.empty()) { POP(y, x1, x2, dy); for (x = x1; (x >= 0) && image.pixel(x, y) == oldColor; x--) { image.setPixel(x, y, newColor); modified.emplace_back(x, y); } if (x >= x1) { goto skip; } l = x + 1; if (l < x1) { PUSH(y, l, x1 - 1, -dy); } x = x1 + 1; do { for (; (x < image.width()) && image.pixel(x, y) == oldColor; x++) { image.setPixel(x, y, newColor); modified.emplace_back(x, y); } PUSH(y, l, x - 1, dy); if (x > x2 + 1) { PUSH(y, x2 + 1, x - 1, -dy); } skip: for (x++; x <= x2 && image.pixel(x, y) != oldColor; x++) { /* empty */ ; } l = x; } while (x <= x2); } } return modified; }
bool DBTalker::addPhoto(const QString& imgPath, const QString& uploadFolder, bool rescale, int maxDim, int imageQuality) { if(m_job) { m_job->kill(); m_job = 0; } emit signalBusy(true); MPForm form; QString path = imgPath; QImage image; if(KPMetadata::isRawFile(imgPath)) { KDcrawIface::KDcraw::loadRawPreview(image,imgPath); } else { image.load(imgPath); } if(image.isNull()) { return false; } path = KStandardDirs::locateLocal("tmp",QFileInfo(imgPath).baseName().trimmed()+".jpg"); if(rescale && (image.width() > maxDim || image.height() > maxDim)) { image = image.scaled(maxDim,maxDim,Qt::KeepAspectRatio,Qt::SmoothTransformation); } image.save(path,"JPEG",imageQuality); KPMetadata meta; if(meta.load(imgPath)) { meta.setImageDimensions(image.size()); meta.setImageProgramId("Kipi-plugins",kipiplugins_version); meta.save(path); } if(!form.addFile(path)) { emit signalBusy(false); return false; } QString uploadPath = uploadFolder + KUrl(imgPath).fileName(); QString m_url = QString("https://api-content.dropbox.com/1/files_put/dropbox/") + "/" +uploadPath; KUrl url(m_url); url.addQueryItem("oauth_consumer_key",m_oauth_consumer_key); url.addQueryItem("oauth_nonce", nonce); url.addQueryItem("oauth_signature",m_access_oauth_signature); url.addQueryItem("oauth_signature_method",m_oauth_signature_method); url.addQueryItem("oauth_timestamp", QString::number(timestamp)); url.addQueryItem("oauth_version",m_oauth_version); url.addQueryItem("oauth_token",m_oauthToken); url.addQueryItem("overwrite","false"); KIO::TransferJob* const job = KIO::http_post(url,form.formData(),KIO::HideProgressInfo); job->addMetaData("content-type","Content-Type : application/x-www-form-urlencoded"); connect(job,SIGNAL(data(KIO::Job*,QByteArray)), this,SLOT(data(KIO::Job*,QByteArray))); connect(job,SIGNAL(result(KJob*)), this,SLOT(slotResult(KJob*))); m_state = DB_ADDPHOTO; m_job = job; m_buffer.resize(0); emit signalBusy(true); return true; }
void MessageBoxInstance::startExecution() { bool ok = true; QString message = evaluateString(ok, "message"); QString title = evaluateString(ok, "title"); Icon icon = evaluateListElement<Icon>(ok, icons, "icon"); TextMode textMode = evaluateListElement<TextMode>(ok, textmodes, "textMode"); Buttons button = evaluateListElement<Buttons>(ok, buttons, "type"); QImage customIcon = evaluateImage(ok, "customIcon"); QImage windowIcon = evaluateImage(ok, "windowIcon"); mIfYes = evaluateIfAction(ok, "ifYes"); mIfNo = evaluateIfAction(ok, "ifNo"); mMessageBox = 0; if(!ok) return; mMessageBox = new QMessageBox(); mMessageBox->setIcon(messageBoxIcon(icon)); mMessageBox->setWindowModality(Qt::NonModal); mMessageBox->setText(message); mMessageBox->setWindowTitle(title); mMessageBox->setWindowFlags(mMessageBox->windowFlags() | Qt::WindowContextHelpButtonHint); switch(textMode) { case HtmlTextMode: mMessageBox->setTextFormat(Qt::RichText); break; case PlainTextMode: mMessageBox->setTextFormat(Qt::PlainText); break; case AutoTextMode: default: mMessageBox->setTextFormat(Qt::AutoText); break; } if(!customIcon.isNull()) mMessageBox->setIconPixmap(QPixmap::fromImage(customIcon)); if(!windowIcon.isNull()) mMessageBox->setWindowIcon(QPixmap::fromImage(windowIcon)); switch(button) { case OkButton: mMessageBox->setStandardButtons(QMessageBox::Ok); break; case YesNoButtons: mMessageBox->setStandardButtons(QMessageBox::Yes | QMessageBox::No); break; } mMessageBox->adjustSize(); QRect screenGeometry = QApplication::desktop()->availableGeometry(); mMessageBox->move(screenGeometry.center()); mMessageBox->move(mMessageBox->pos().x() - mMessageBox->width()/2, mMessageBox->pos().y() - mMessageBox->height()/2); mMessageBox->open(this, SLOT(buttonClicked())); }
QFileInfo Content::GetImageFile( const QString &sStorageGroup, const QString &sFileName, int nWidth, int nHeight) { QString sGroup = sStorageGroup; if (sGroup.isEmpty()) { LOG(VB_UPNP, LOG_WARNING, "GetImageFile - StorageGroup missing... using 'Default'"); sGroup = "Default"; } if (sFileName.isEmpty()) { QString sMsg ( "GetImageFile - FileName missing." ); //LOG(VB_UPNP, LOG_WARNING, sMsg); throw sMsg; } // ------------------------------------------------------------------ // Search for the filename // ------------------------------------------------------------------ StorageGroup storage( sGroup ); QString sFullFileName = storage.FindFile( sFileName ); if (sFullFileName.isEmpty()) { LOG(VB_UPNP, LOG_WARNING, QString("GetImageFile - Unable to find %1.").arg(sFileName)); return QFileInfo(); } // ---------------------------------------------------------------------- // check to see if the file (still) exists // ---------------------------------------------------------------------- if (!QFile::exists( sFullFileName )) { LOG(VB_UPNP, LOG_WARNING, QString("GetImageFile - File Does not exist %1.").arg(sFullFileName)); return QFileInfo(); } // ---------------------------------------------------------------------- // If no scaling is required return the file info // ---------------------------------------------------------------------- if ((nWidth == 0) && (nHeight == 0)) return QFileInfo( sFullFileName ); // ---------------------------------------------------------------------- // Create a filename for the scaled copy // ---------------------------------------------------------------------- QString sNewFileName = QString( "%1.%2x%3.jpg" ) .arg( sFullFileName ) .arg( nWidth ) .arg( nHeight ); // ---------------------------------------------------------------------- // check to see if image is already created. // ---------------------------------------------------------------------- if (QFile::exists( sNewFileName )) return QFileInfo( sNewFileName ); // ---------------------------------------------------------------------- // Must generate Generate Image and save. // ---------------------------------------------------------------------- float fAspect = 0.0; QImage *pImage = new QImage( sFullFileName ); if (!pImage || pImage->isNull()) return QFileInfo(); if (fAspect <= 0) fAspect = (float)(pImage->width()) / pImage->height(); if ( nWidth == 0 ) nWidth = (int)rint(nHeight * fAspect); if ( nHeight == 0 ) nHeight = (int)rint(nWidth / fAspect); QImage img = pImage->scaled( nWidth, nHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); QByteArray fname = sNewFileName.toLatin1(); img.save( fname.constData(), "JPG", 60 ); delete pImage; return QFileInfo( sNewFileName ); }
bool VideoGrabber::openReader() { PAssert( !videoReader, "Opening video reader that already exists." ); unsigned minw, minh, maxw, maxh, width, height; QImage image; ancaInfo->setInt( VG_STATE, VG_OPENING ); QString videoDevice = ancaConf->readEntry( "videoin", "videoDevice", (const char *)PVideoChannel::GetDefaultDevice(PVideoChannel::Recorder) ); int videoChannel = ancaConf->readIntEntry( "videoin", "videoChannel", -1 ); int videoFormat = ancaConf->readIntEntry( "videoin", "videoFormat", PVideoDevice::Auto ); int videoFrameRate = ancaConf->readIntEntry( "videoin", "videoFrameRate", 0 ); QString videoImage = ancaConf->readEntry( "videoin", "videoImage", QString::null ); if( args->HasOption("videoformat") ) { PString tmp = args->GetOptionString("videoformat"); if( tmp *= "auto" ) videoFormat = PVideoDevice::Auto; else if( tmp *= "pal" ) videoFormat = PVideoDevice::PAL; else if( tmp *= "ntsc" ) videoFormat = PVideoDevice::NTSC; } if( args->HasOption("videodevice") ) videoDevice = (const char *)args->GetOptionString("videodevice"); videoReader = new PVideoInputDevice(); //videoReader = new PFakeVideoInputDevice(); if ( !videoReader ) { PTRACE( 1, "Allocation of videoReader failed!" ); return false; } else PTRACE( 6, "VideoReader allocated" ); if ( !videoReader->Open( videoDevice.latin1(), false ) ) { PTRACE( 1, "Open failed" ); goto video_error; } else PTRACE( 6, "VideoReader opened" ); if ( !videoReader->SetColourFormatConverter( "YUV420P" ) ) { PTRACE( 1, "SetColourFormatConverter failed" ); goto video_error; } else PTRACE( 6, "SetColourFormatConverter succeeded" ); if ( !videoReader->SetChannel( videoChannel ) ) { PTRACE( 1, "SetChannel failed" ); goto video_error; } else PTRACE( 6, "SetChannel succeeded" ); if ( !videoReader->SetVideoFormat( ( PVideoDevice::VideoFormat ) videoFormat ) ) { PTRACE( 1, "SetVideoFormat failed" ); goto video_error; } else PTRACE( 6, "SetVideoFormat succeeded" ); if ( !videoReader->SetFrameRate( videoFrameRate ) ) { PTRACE( 1, "SetFrameRate failed" ); goto video_error; } else PTRACE( 6, "SetFrameRate succeeded" ); videoReader->GetFrameSizeLimits( minw, minh, maxw, maxh ); configureVideoFrameSize( maxw, maxh, width, height ); if (!videoReader->SetFrameSizeConverter(width, height, FALSE)) { PTRACE(1, "Failed to set framesize to " << width<< "x" << height); goto video_error; } else PTRACE( 6, "SetFrameSizeConverter succeeded to set frame to " << width<< "x" << height); goto start_video_reader; video_error: PTRACE( 1, "Error while opening video device. The chosen video image will be transmitted instead." ); delete videoReader; if( args->HasOption("videoimage") ) videoImage = (const char *)args->GetOptionString("videoimage"); image.load(videoImage); videoReader = new FakeVideoInputDevice( image ); videoReader->SetColourFormatConverter ("YUV420P"); videoReader->SetVideoFormat (PVideoDevice::PAL); videoReader->SetChannel (1); videoReader->SetFrameRate (6); videoReader->GetFrameSizeLimits( minw, minh, maxw, maxh ); configureVideoFrameSize( maxw, maxh, width, height ); videoReader->SetFrameSizeConverter (width, height, FALSE); start_video_reader: videoReader->Start(); channel->AttachVideoReader( videoReader ); ancaInfo->setInt( VG_STATE, VG_OPENED ); return true; }
QFileInfo Content::GetPreviewImage( int nRecordedId, int nChanId, const QDateTime &recstarttsRaw, int nWidth, int nHeight, int nSecsIn, const QString &sFormat ) { if ((nRecordedId <= 0) && (nChanId <= 0 || !recstarttsRaw.isValid())) throw QString("Recorded ID or Channel ID and StartTime appears invalid."); if (!sFormat.isEmpty() && !QImageWriter::supportedImageFormats().contains(sFormat.toLower().toLocal8Bit())) { throw "GetPreviewImage: Specified 'Format' is not supported."; } // ---------------------------------------------------------------------- // Read Recording From Database // ---------------------------------------------------------------------- // TODO Should use RecordingInfo ProgramInfo pginfo; if (nRecordedId > 0) pginfo = ProgramInfo(nRecordedId); else pginfo = ProgramInfo(nChanId, recstarttsRaw.toUTC()); if (!pginfo.GetChanID()) { LOG(VB_GENERAL, LOG_ERR, QString("GetPreviewImage: No recording for '%1'") .arg(nRecordedId)); return QFileInfo(); } if (pginfo.GetHostname().toLower() != gCoreContext->GetHostName().toLower()) { QString sMsg = QString("GetPreviewImage: Wrong Host '%1' request from '%2'") .arg( gCoreContext->GetHostName()) .arg( pginfo.GetHostname() ); LOG(VB_UPNP, LOG_ERR, sMsg); throw HttpRedirectException( pginfo.GetHostname() ); } QString sImageFormat = sFormat; if (sImageFormat.isEmpty()) sImageFormat = "PNG"; QString sFileName = GetPlaybackURL(&pginfo); // ---------------------------------------------------------------------- // check to see if default preview image is already created. // ---------------------------------------------------------------------- QString sPreviewFileName; if (nSecsIn <= 0) { nSecsIn = -1; sPreviewFileName = QString("%1.png").arg(sFileName); } else { sPreviewFileName = QString("%1.%2.png").arg(sFileName).arg(nSecsIn); } if (!QFile::exists( sPreviewFileName )) { // ------------------------------------------------------------------ // Must generate Preview Image, Generate Image and save. // ------------------------------------------------------------------ if (!pginfo.IsLocal() && sFileName.startsWith("/")) pginfo.SetPathname(sFileName); if (!pginfo.IsLocal()) return QFileInfo(); PreviewGenerator *previewgen = new PreviewGenerator( &pginfo, QString(), PreviewGenerator::kLocal); previewgen->SetPreviewTimeAsSeconds( nSecsIn ); previewgen->SetOutputFilename ( sPreviewFileName ); bool ok = previewgen->Run(); previewgen->deleteLater(); if (!ok) return QFileInfo(); } bool bDefaultPixmap = (nWidth == 0) && (nHeight == 0); QString sNewFileName; if (bDefaultPixmap) sNewFileName = sPreviewFileName; else { sNewFileName = QString( "%1.%2.%3x%4.%5" ) .arg( sFileName ) .arg( nSecsIn ) .arg( nWidth == 0 ? -1 : nWidth ) .arg( nHeight == 0 ? -1 : nHeight ) .arg( sImageFormat.toLower() ); // ---------------------------------------------------------------------- // check to see if scaled preview image is already created and isn't // out of date // ---------------------------------------------------------------------- if (QFile::exists( sNewFileName )) { if (QFileInfo(sPreviewFileName).lastModified() <= QFileInfo(sNewFileName).lastModified()) return QFileInfo( sNewFileName ); } QImage image = QImage(sPreviewFileName); if (image.isNull()) return QFileInfo(); // We can just re-scale the default (full-size version) to avoid // a preview generator run if ( nWidth <= 0 ) image = image.scaledToHeight(nHeight, Qt::SmoothTransformation); else if ( nHeight <= 0 ) image = image.scaledToWidth(nWidth, Qt::SmoothTransformation); else image = image.scaled(nWidth, nHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); image.save(sNewFileName, sImageFormat.toUpper().toLocal8Bit()); // Let anybody update it bool ret = makeFileAccessible(sNewFileName.toLocal8Bit().constData()); if (!ret) { LOG(VB_GENERAL, LOG_ERR, "Unable to change permissions on " "preview image. Backends and frontends " "running under different users will be " "unable to access it"); } } if (QFile::exists( sNewFileName )) return QFileInfo( sNewFileName ); PreviewGenerator *previewgen = new PreviewGenerator( &pginfo, QString(), PreviewGenerator::kLocal); previewgen->SetPreviewTimeAsSeconds( nSecsIn ); previewgen->SetOutputFilename ( sNewFileName ); previewgen->SetOutputSize (QSize(nWidth,nHeight)); bool ok = previewgen->Run(); previewgen->deleteLater(); if (!ok) return QFileInfo(); return QFileInfo( sNewFileName ); }
// Thanks StackOverflow for this algorithm (works like a charm without any changes) QImage ImageUtils::blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly) { int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }; int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1]; QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); int r1 = rect.top(); int r2 = rect.bottom(); int c1 = rect.left(); int c2 = rect.right(); int bpl = result.bytesPerLine(); int rgba[4]; unsigned char* p; int i1 = 0; int i2 = 3; if (alphaOnly) i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); for (int col = c1; col <= c2; col++) { p = result.scanLine(r1) + col * 4; for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p += bpl; for (int j = r1; j < r2; j++, p += bpl) for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int row = r1; row <= r2; row++) { p = result.scanLine(row) + c1 * 4; for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p += 4; for (int j = c1; j < c2; j++, p += 4) for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int col = c1; col <= c2; col++) { p = result.scanLine(r2) + col * 4; for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p -= bpl; for (int j = r1; j < r2; j++, p -= bpl) for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int row = r1; row <= r2; row++) { p = result.scanLine(row) + c2 * 4; for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p -= 4; for (int j = c1; j < c2; j++, p -= 4) for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } return result; }