QPixmap
ImageRegistry::pixmap( const QString& image, const QSize& size, TomahawkUtils::ImageMode mode, float opacity, QColor tint )
{
    if ( size.width() < 0 || size.height() < 0 )
    {
        Q_ASSERT( false );
        return QPixmap();
    }

    QHash< qint64, QPixmap > subsubcache;
    QHash< int, QHash< qint64, QPixmap > > subcache;

    if ( s_cache.contains( image ) )
    {
        subcache = s_cache.value( image );

        if ( subcache.contains( mode ) )
        {
            subsubcache = subcache.value( mode );

            const qint64 ck = cacheKey( size, opacity, tint );
            if ( subsubcache.contains( ck ) )
            {
                return subsubcache.value( ck );
            }
        }
    }

    // Image not found in cache. Let's load it.
    QPixmap pixmap;
    if ( image.toLower().endsWith( ".svg" ) )
    {
        QSvgRenderer svgRenderer( image );
        QPixmap p( size.isNull() || size.height() == 0 || size.width() == 0 ? svgRenderer.defaultSize() : size );
        p.fill( Qt::transparent );

        QPainter pixPainter( &p );
        pixPainter.setOpacity( opacity );
        svgRenderer.render( &pixPainter );
        pixPainter.end();

        if ( tint.alpha() > 0 )
            p = TomahawkUtils::tinted( p, tint );

        pixmap = p;
    }
    else
        pixmap = QPixmap( image );

    if ( !pixmap.isNull() )
    {
        switch ( mode )
        {
            case TomahawkUtils::RoundedCorners:
                pixmap = TomahawkUtils::createRoundedImage( pixmap, size );
                break;

            default:
                break;
        }

        if ( !size.isNull() && pixmap.size() != size )
        {
            if ( size.width() == 0 )
            {
                pixmap = pixmap.scaledToHeight( size.height(), Qt::SmoothTransformation );
            }
            else if ( size.height() == 0 )
            {
                pixmap = pixmap.scaledToWidth( size.width(), Qt::SmoothTransformation );
            }
            else
                pixmap = pixmap.scaled( size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
        }

        putInCache( image, size, mode, opacity, pixmap, tint );
    }

    return pixmap;
}
Exemple #2
0
/**
 *  \brief Load the image(s), wraps LoadImage()
 */
bool MythUIImage::Load(bool allowLoadInBackground, bool forceStat)
{
    d->m_UpdateLock.lockForRead();

    QSize bForceSize = m_ForceSize;
    QString bFilename = m_Filename;
    bFilename.detach();

    d->m_UpdateLock.unlock();

    QString filename = bFilename;

    if (bFilename.isEmpty())
    {
        Clear();
        SetRedraw();

        return false;
    }

    Clear();

//    SetRedraw();

//    if (!IsVisible(true))
//        return false;

    int w = -1;
    int h = -1;

    if (!bForceSize.isNull())
    {
        if (bForceSize.width() != -1)
            w = bForceSize.width();

        if (bForceSize.height() != -1)
            h = bForceSize.height();
    }

    QString imagelabel;

    int j = 0;
    for (int i = m_LowNum; i <= m_HighNum && !m_animatedImage; i++)
    {
        if (!m_animatedImage && m_HighNum != m_LowNum && 
            bFilename.contains("%1"))
            filename = bFilename.arg(i);

        imagelabel = GenImageLabel(filename, w, h);

        // Only load in the background if allowed and the image is
        // not already in our mem cache
        ImageCacheMode cacheMode = kCacheCheckMemoryOnly;
        if (forceStat)
            cacheMode = (ImageCacheMode)
                ((int)kCacheCheckMemoryOnly | (int)kCacheForceStat);

        ImageCacheMode cacheMode2 = (!forceStat) ? kCacheNormal :
            (ImageCacheMode) ((int)kCacheNormal | (int)kCacheForceStat);


        if ((allowLoadInBackground) &&
            (!GetMythUI()->LoadCacheImage(filename, imagelabel,
                                          GetPainter(), cacheMode)) &&
            (!getenv("DISABLETHREADEDMYTHUIIMAGE")))
        {
            VERBOSE(VB_GUI|VB_FILE|VB_EXTRA, LOC + QString(
                        "Load(), spawning thread to load '%1'").arg(filename));
            ImageLoadThread *bImgThread = new ImageLoadThread(
                this, bFilename, filename, i, bForceSize, cacheMode2);
            GetMythUI()->GetImageThreadPool()->start(bImgThread);
        }
        else
        {
            // Perform a blocking load
            VERBOSE(VB_GUI|VB_FILE|VB_EXTRA, LOC + QString(
                        "Load(), loading '%1' in foreground").arg(filename));
            QString tmpFilename;
            if ((filename.startsWith("/")) ||
                (filename.startsWith("http://")) ||
                (filename.startsWith("https://")) ||
                (filename.startsWith("ftp://")))
                tmpFilename = filename;

            MythImageReader imageReader(tmpFilename);

            if (imageReader.supportsAnimation())
            {
                LoadAnimatedImage(
                    imageReader, filename, bForceSize, cacheMode2);
            }
            else
            {
                MythImage *image = LoadImage(
                    imageReader, filename, bForceSize, cacheMode2);
                if (image)
                {
                    if (bForceSize.isNull())
                        SetSize(image->size());

                    m_ImagesLock.lock();
                    m_Images[j] = image;
                    m_ImagesLock.unlock();

                    SetRedraw();
                    d->m_UpdateLock.lockForWrite();
                    m_LastDisplay = QTime::currentTime();
                    d->m_UpdateLock.unlock();
                }
                else
                {
                    m_ImagesLock.lock();
                    m_Images[j] = NULL;
                    m_ImagesLock.unlock();
                }
            }
        }
        ++j;
    }

    return true;
}
Exemple #3
0
/**
*  \brief Load an animated image
*/
bool MythUIImage::LoadAnimatedImage(
    MythImageReader &imageReader, const QString &imFile,
    QSize bForceSize, int cacheMode)
{
    bool result = false;
    m_loadingImagesLock.lock();

    // Check to see if the image is being loaded by us in another thread
    if ((m_loadingImages.contains(imFile)) &&
        (m_loadingImages[imFile] == this))
    {
        VERBOSE(VB_GUI|VB_FILE|VB_EXTRA, LOC + QString(
                    "MythUIImage::LoadAnimatedImage(%1), this "
                    "file is already being loaded by this same MythUIImage in "
                    "another thread.").arg(imFile));
        m_loadingImagesLock.unlock();
        return result;
    }

    // Check to see if the exact same image is being loaded anywhere else
    while (m_loadingImages.contains(imFile))
        m_loadingImagesCond.wait(&m_loadingImagesLock);

    m_loadingImages[imFile] = this;
    m_loadingImagesLock.unlock();

    QString filename = QString("frame-%1-") + imFile;
    QString frameFilename;
    QVector<MythImage *> images;
    QVector<int> delays;
    int imageCount = 1;
    QString imageLabel;

    int w = -1;
    int h = -1;

    if (!bForceSize.isNull())
    {
        if (bForceSize.width() != -1)
            w = bForceSize.width();

        if (bForceSize.height() != -1)
            h = bForceSize.height();
    }

    while (imageReader.canRead())
    {
        frameFilename = filename.arg(imageCount);
        imageLabel = GenImageLabel(frameFilename, w, h);
        MythImage *im = LoadImage(
            imageReader, frameFilename,
            bForceSize, (ImageCacheMode) cacheMode);

        if (!im)
            break;

        images.append(im);
        delays.append(imageReader.nextImageDelay());
        imageCount++;
    }

    if (images.size())
    {
        m_animatedImage = true;
        SetImages(images);
        if ((m_Delay == -1) &&
            (imageReader.supportsAnimation()) &&
            (delays.size()))
        {
            SetDelays(delays);
        }
        result = true;
    }

    m_loadingImagesLock.lock();
    m_loadingImages.remove(imFile);
    m_loadingImagesCond.wakeAll();
    m_loadingImagesLock.unlock();

    return result;
}
Exemple #4
0
/**
 *  \brief Assign a set of MythImages to the widget for animation.
 *         Use is strongly discouraged, use SetFilepattern() instead.
 *
 */
void MythUIImage::SetImages(QVector<MythImage *> *images)
{
    Clear();

    QWriteLocker updateLocker(&d->m_UpdateLock);
    QSize aSize = GetFullArea().size();

    m_imageProperties.isThemeImage = false;

    QVector<MythImage *>::iterator it;

    for (it = images->begin(); it != images->end(); ++it)
    {
        MythImage *im = (*it);

        if (!im)
        {
            QMutexLocker locker(&m_ImagesLock);
            m_Images[m_Images.size()] = im;
            continue;
        }

        im->IncrRef();


        QSize forceSize = m_imageProperties.forceSize;
        if (!forceSize.isNull())
        {
            int w = (forceSize.width() <= 0) ? im->width() : forceSize.width();
            int h = (forceSize.height() <= 0) ? im->height() : forceSize.height();
            im->Resize(QSize(w, h), m_imageProperties.preserveAspect);
        }

        if (m_imageProperties.isReflected && !im->IsReflected())
            im->Reflect(m_imageProperties.reflectAxis,
                        m_imageProperties.reflectShear,
                        m_imageProperties.reflectScale,
                        m_imageProperties.reflectLength,
                        m_imageProperties.reflectSpacing);

        if (m_imageProperties.isGreyscale && !im->isGrayscale())
            im->ToGreyscale();

        if (m_imageProperties.isOriented && !im->IsOriented())
            im->Orientation(m_imageProperties.orientation);

        m_ImagesLock.lock();
        m_Images[m_Images.size()] = im;
        m_ImagesLock.unlock();

        aSize = aSize.expandedTo(im->size());
    }

    SetImageCount(1, m_Images.size());

    if (m_imageProperties.forceSize.isNull())
        SetSize(aSize);

    MythRect rect(GetFullArea());
    rect.setSize(aSize);
    SetMinArea(rect);

    m_CurPos = 0;
    m_animatedImage = true;
    m_Initiator = m_EnableInitiator;
    SetRedraw();
}