Пример #1
0
bool toGif(QImage& img, QString& path)
{
    int errcode;

    if(QFile(path).exists()) // Remove old file
        QFile::remove(path);

    GifFileType* t = EGifOpenFileName(path.toLocal8Bit().data(),true, &errcode);
    if(!t){
        EGifCloseFile(t, &errcode);
        QTextStream(stdout)  << "Can't open\n";
        return false;
    }

    EGifSetGifVersion(t, true);

    GifColorType* colorArr = new GifColorType[256];
    ColorMapObject* cmo = GifMakeMapObject(256, colorArr);

    bool unfinished = false;
    QImage tarQImg(img.width(), img.height(), QImage::Format_Indexed8);
    QVector<QRgb> table;
    for(int y = 0; y < img.height(); y++){
        for(int x = 0; x < img.width(); x++){
            if(table.size() >= 256){
                unfinished = true;
                break;
            }
            QRgb pix;
            if(!table.contains(pix = img.pixel(x,y))){
                table.push_back(pix);
                tarQImg.setColor(tarQImg.colorCount(), pix);
            }
            tarQImg.setPixel(x,y,table.indexOf(pix));
        }
        if(table.size() >= 256){
            unfinished = true;
            break;
        }
    }

    if(unfinished){
        EGifCloseFile(t, &errcode);
        QTextStream(stdout)  << "Unfinished\n";
        return false;
    }


    for(int l = tarQImg.colorCount(); l < 256; l++){
        tarQImg.setColor(l,0);
    }

    if(tarQImg.colorTable().size() != 256){
        EGifCloseFile(t, &errcode);
        QTextStream(stdout)  << "A lot of colors\n";
        return false;
    }

    QVector<QRgb> clTab = tarQImg.colorTable();

    for(int i = 0; i < 255; i++){
        QRgb rgb = clTab[i];
        colorArr[i].Red = qRed(rgb);
        colorArr[i].Green = qGreen(rgb);
        colorArr[i].Blue = qBlue(rgb);
    }
    cmo->Colors = colorArr;

    errcode = EGifPutScreenDesc(t, img.width(), img.height(), 256, 0, cmo);
    if(errcode != GIF_OK){
        EGifCloseFile(t, &errcode);
        QTextStream(stdout)  << "EGifPutScreenDesc error 1\n";
        return false;
    }

    errcode = EGifPutImageDesc(t, 0, 0, img.width(), img.height(), false, 0);
    if(errcode != GIF_OK){
        EGifCloseFile(t, &errcode);
        QTextStream(stdout)  << "EGifPutImageDesc error 2\n";
        return false;
    }

    //gen byte array
    GifByteType* byteArr = tarQImg.bits();

    for(int h = 0; h < tarQImg.height(); h++){
        errcode = EGifPutLine(t, byteArr, tarQImg.width());
        if(errcode != GIF_OK){
            EGifCloseFile(t, &errcode);
            QTextStream(stdout)  << "EGifPutLine error 3\n";
            return false;
        }

        byteArr += tarQImg.width();
        byteArr += ((tarQImg.width() % 4)!=0 ? 4 - (tarQImg.width() % 4) : 0);
    }

    if(errcode != GIF_OK){
        QTextStream(stdout)  << "GIF error 4\n";
        return false;
    }
    EGifCloseFile(t, &errcode);

    return true;
}
Пример #2
0
bool Graphics::toGif(QImage &img, QString &path)
{
    int errcode;

    if(QFile(path).exists()) // Remove old file
        QFile::remove(path);

    GifFileType *t = EGifOpenFileName(path.toStdString().c_str(), true, &errcode);

    if(!t)
    {
        EGifCloseFile(t, &errcode);
        std::cout << "Can't open\n";
        return false;
    }

    EGifSetGifVersion(t, true);
    std::vector<GifColorType>colorArr;
    colorArr.resize(256);
    ColorMapObject *cmo = GifMakeMapObject(256, colorArr.data());
    bool unfinished = false;
    QImage tarQImg(img.width(), img.height(), QImage::Format_Indexed8);
    QVector<QRgb> table;

    for(int y = 0; y < img.height(); y++)
    {
        for(int x = 0; x < img.width(); x++)
        {
            if(table.size() >= 256)
            {
                unfinished = true;
                break;
            }

            QRgb pix;

            if(!table.contains(pix = img.pixel(x, y)))
            {
                table.push_back(pix);
                tarQImg.setColor(tarQImg.colorCount(), pix);
            }

            tarQImg.setPixel(x, y, static_cast<uint>(table.indexOf(pix)));
        }

        if(table.size() >= 256)
        {
            unfinished = true;
            break;
        }
    }

    if(unfinished)
    {
        GifFreeMapObject(cmo);
        EGifCloseFile(t, &errcode);
        std::cout << "Unfinished\n";
        return false;
    }

    for(int l = tarQImg.colorCount(); l < 256; l++)
        tarQImg.setColor(l, 0);

    if(tarQImg.colorTable().size() != 256)
    {
        GifFreeMapObject(cmo);
        EGifCloseFile(t, &errcode);
        std::cout << "A lot of colors\n";
        return false;
    }

    std::vector<QRgb> clTab = tarQImg.colorTable().toStdVector();

    for(size_t i = 0; i < 255; i++)
    {
        QRgb rgb = clTab[i];
        colorArr[i].Red     = static_cast<unsigned char>(qRed(rgb));
        colorArr[i].Green   = static_cast<unsigned char>(qGreen(rgb));
        colorArr[i].Blue    = static_cast<unsigned char>(qBlue(rgb));
    }

    cmo->Colors = colorArr.data();
    errcode = EGifPutScreenDesc(t, img.width(), img.height(), 256, 0, cmo);

    if(errcode != GIF_OK)
    {
        GifFreeMapObject(cmo);
        EGifCloseFile(t, &errcode);
        std::cout << "EGifPutScreenDesc error 1\n";
        return false;
    }

    errcode = EGifPutImageDesc(t, 0, 0, img.width(), img.height(), false, 0);

    if(errcode != GIF_OK)
    {
        GifFreeMapObject(cmo);
        EGifCloseFile(t, &errcode);
        std::cout << "EGifPutImageDesc error 2\n";
        return false;
    }

    //gen byte array
    GifByteType *byteArr = tarQImg.bits();

    for(int h = 0; h < tarQImg.height(); h++)
    {
        errcode = EGifPutLine(t, byteArr, tarQImg.width());

        if(errcode != GIF_OK)
        {
            GifFreeMapObject(cmo);
            EGifCloseFile(t, &errcode);
            std::cout << "EGifPutLine error 3\n";
            return false;
        }

        byteArr += tarQImg.width();
        byteArr += ((tarQImg.width() % 4) != 0 ? 4 - (tarQImg.width() % 4) : 0);
    }

    GifFreeMapObject(cmo);
    EGifCloseFile(t, &errcode);
    return true;
}