mavzermete 1
mavzermete
Bvural41 1
Bvural41
Hikaye Ekle

Client'e gif desteği ekleme

  • Konuyu başlatan Konuyu başlatan Koray'
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 31
  • Görüntüleme Görüntüleme 7K
Konuya ek bir güncelleme yapmak istiyorum BMP formatında 24 bit işleme yapıyoruz bundan dolayı alphachannel mevcut değil yani transparanlıkları doğru şekilde işleyemiyoruz.


Bu yüzden dolayı kodu biraz modifiye ettim aşağıdaki şekilde düzenlerseniz daha uygun olacaktır.

Orijinal halindeki gif çıktısı


Benim düzenlememdeki halindeki gif çıktısı



Kod:
    PythonWindow.cpp

// includeler arasına ekle
#include <array>

// Orijinaldeki kodu aşağıdaki şekilde değiştir.

    bool RawFrameToTGAImage(SavedImage* currentFrame, GifFileType* gifFile, std::vector <uint8_t>& outData)
    {
        if (!currentFrame || !gifFile)
        {
            TraceError("RawFrameToTGAImage: Invalid parameters.");
            return false;
        }

        auto& imageDesc = currentFrame->ImageDesc;
        auto* colorMap = (imageDesc.ColorMap) ? imageDesc.ColorMap : gifFile->SColorMap;
        if (!colorMap)
        {
            TraceError("RawFrameToTGAImage: ColorMap is null.");
            return false;
        }

        const int width = imageDesc.Width;
        const int height = imageDesc.Height;

        // TGA Header
        std::array<uint8_t, 18> header = {0};
        header[2] = 2; // Uncompressed RGB
        header[12] = width & 0xFF;
        header[13] = (width >> 8) & 0xFF;
        header[14] = height & 0xFF;
        header[15] = (height >> 8) & 0xFF;
        header[16] = 32; // 32 bits per pixel

        outData.insert(outData.end(), header.begin(), header.end());

        // Get transparency information from the GIF
        GraphicsControlBlock gcb;
        DGifSavedExtensionToGCB(gifFile, currentFrame - gifFile->SavedImages, &gcb);

        for (int y = height - 1; y >= 0; --y)
        {
            for (int x = 0; x < width; ++x)
            {
                const int index = y * width + x;
                const GifByteType colorIndex = currentFrame->RasterBits[index];
                if (colorIndex < colorMap->ColorCount)
                {
                    const GifColorType& gifColor = colorMap->Colors[colorIndex];
                    outData.push_back(gifColor.Blue);
                    outData.push_back(gifColor.Green);
                    outData.push_back(gifColor.Red);
                    // If the pixel is transparent in the GIF, make it transparent in the TGA
                    outData.push_back((gcb.TransparentColor && colorIndex == gcb.TransparentColor) ? 0x00 : 0xFF);
                }
                else
                {
                    TraceError("RawFrameToTGAImage: Color index out of range.");
                    return false;
                }
            }
        }

        return true;
    }


    bool CGifImageBox::LoadGif(const char* c_szFileName)
    {
        if (!c_szFileName || !*c_szFileName)
            return false;

        // Open GIF file
        int error;
        GifFileType* gif = DGifOpenFileName(c_szFileName, &error);
        if (!gif)
        {
            const char* c_szError = GifErrorString(error);
            TraceError("Failed to open GIF file: %s with error: %s", c_szFileName, c_szError);
            return false;
        }

        // Read the GIF into memory
        if (DGifSlurp(gif) == GIF_ERROR)
        {
            TraceError("Failed to read GIF file: %s", c_szFileName);
            DGifCloseFile(gif, &error);
            return false;
        }

        // Iterate through the frames
        for (int i = 0; i < gif->ImageCount; ++i)
        {
            // Get the current frame
            SavedImage* currentImage = &gif->SavedImages[i];

            // Convert the frame to TGA image
            std::vector <uint8_t> tgaBuffer;
            if (!RawFrameToTGAImage(currentImage, gif, tgaBuffer))
            {
                TraceError("Failed to convert GIF(%s) frame #%d to TGA image.", c_szFileName, i);
                continue;
            }

            // Create name for the frame
            char frameFileName[256]{ '\0' };
            snprintf(frameFileName, sizeof(frameFileName), "gif_frame%d_%s", i, c_szFileName);

            // Create the image instance
            CGraphicImage* pImage = new CGraphicImage(frameFileName, tgaBuffer.data(), tgaBuffer.size(), D3DX_FILTER_LINEAR);
            if (!pImage)
            {
                TraceError("Failed to create image instance for GIF(%s) frame #%d.", c_szFileName, i);
                continue;
            }

            // Create the expanded image instance
            CGraphicExpandedImageInstance* pImageInstance = CGraphicExpandedImageInstance::New();
            pImageInstance->SetImagePointer(pImage);

            // Add the image instance to the vector if it's not empty
            if (pImageInstance->IsEmpty())
            {
                CGraphicExpandedImageInstance::Delete(pImageInstance);
            }
            else
            {
                pImageInstance->SetPosition(m_rect.left, m_rect.top);
                m_ImageVector.push_back(pImageInstance);
            }
        }

        // Clean up
        DGifCloseFile(gif, &error);

        return true;
    }


@Koray' istersen konuya ekleme yapabilirsin.


Keyifli forumlar.
 
Konuya ek bir güncelleme yapmak istiyorum BMP formatında 24 bit işleme yapıyoruz bundan dolayı alphachannel mevcut değil yani transparanlıkları doğru şekilde işleyemiyoruz.


Bu yüzden dolayı kodu biraz modifiye ettim aşağıdaki şekilde düzenlerseniz daha uygun olacaktır.

Orijinal halindeki gif çıktısı


Benim düzenlememdeki halindeki gif çıktısı



Kod:
    PythonWindow.cpp

// includeler arasına ekle
#include <array>

// Orijinaldeki kodu aşağıdaki şekilde değiştir.

    bool RawFrameToTGAImage(SavedImage* currentFrame, GifFileType* gifFile, std::vector <uint8_t>& outData)
    {
        if (!currentFrame || !gifFile)
        {
            TraceError("RawFrameToTGAImage: Invalid parameters.");
            return false;
        }

        auto& imageDesc = currentFrame->ImageDesc;
        auto* colorMap = (imageDesc.ColorMap) ? imageDesc.ColorMap : gifFile->SColorMap;
        if (!colorMap)
        {
            TraceError("RawFrameToTGAImage: ColorMap is null.");
            return false;
        }

        const int width = imageDesc.Width;
        const int height = imageDesc.Height;

        // TGA Header
        std::array<uint8_t, 18> header = {0};
        header[2] = 2; // Uncompressed RGB
        header[12] = width & 0xFF;
        header[13] = (width >> 8) & 0xFF;
        header[14] = height & 0xFF;
        header[15] = (height >> 8) & 0xFF;
        header[16] = 32; // 32 bits per pixel

        outData.insert(outData.end(), header.begin(), header.end());

        // Get transparency information from the GIF
        GraphicsControlBlock gcb;
        DGifSavedExtensionToGCB(gifFile, currentFrame - gifFile->SavedImages, &gcb);

        for (int y = height - 1; y >= 0; --y)
        {
            for (int x = 0; x < width; ++x)
            {
                const int index = y * width + x;
                const GifByteType colorIndex = currentFrame->RasterBits[index];
                if (colorIndex < colorMap->ColorCount)
                {
                    const GifColorType& gifColor = colorMap->Colors[colorIndex];
                    outData.push_back(gifColor.Blue);
                    outData.push_back(gifColor.Green);
                    outData.push_back(gifColor.Red);
                    // If the pixel is transparent in the GIF, make it transparent in the TGA
                    outData.push_back((gcb.TransparentColor && colorIndex == gcb.TransparentColor) ? 0x00 : 0xFF);
                }
                else
                {
                    TraceError("RawFrameToTGAImage: Color index out of range.");
                    return false;
                }
            }
        }

        return true;
    }


    bool CGifImageBox::LoadGif(const char* c_szFileName)
    {
        if (!c_szFileName || !*c_szFileName)
            return false;

        // Open GIF file
        int error;
        GifFileType* gif = DGifOpenFileName(c_szFileName, &error);
        if (!gif)
        {
            const char* c_szError = GifErrorString(error);
            TraceError("Failed to open GIF file: %s with error: %s", c_szFileName, c_szError);
            return false;
        }

        // Read the GIF into memory
        if (DGifSlurp(gif) == GIF_ERROR)
        {
            TraceError("Failed to read GIF file: %s", c_szFileName);
            DGifCloseFile(gif, &error);
            return false;
        }

        // Iterate through the frames
        for (int i = 0; i < gif->ImageCount; ++i)
        {
            // Get the current frame
            SavedImage* currentImage = &gif->SavedImages[i];

            // Convert the frame to TGA image
            std::vector <uint8_t> tgaBuffer;
            if (!RawFrameToTGAImage(currentImage, gif, tgaBuffer))
            {
                TraceError("Failed to convert GIF(%s) frame #%d to TGA image.", c_szFileName, i);
                continue;
            }

            // Create name for the frame
            char frameFileName[256]{ '\0' };
            snprintf(frameFileName, sizeof(frameFileName), "gif_frame%d_%s", i, c_szFileName);

            // Create the image instance
            CGraphicImage* pImage = new CGraphicImage(frameFileName, tgaBuffer.data(), tgaBuffer.size(), D3DX_FILTER_LINEAR);
            if (!pImage)
            {
                TraceError("Failed to create image instance for GIF(%s) frame #%d.", c_szFileName, i);
                continue;
            }

            // Create the expanded image instance
            CGraphicExpandedImageInstance* pImageInstance = CGraphicExpandedImageInstance::New();
            pImageInstance->SetImagePointer(pImage);

            // Add the image instance to the vector if it's not empty
            if (pImageInstance->IsEmpty())
            {
                CGraphicExpandedImageInstance::Delete(pImageInstance);
            }
            else
            {
                pImageInstance->SetPosition(m_rect.left, m_rect.top);
                m_ImageVector.push_back(pImageInstance);
            }
        }

        // Clean up
        DGifCloseFile(gif, &error);

        return true;
    }


@Koray' istersen konuya ekleme yapabilirsin.


Keyifli forumlar.
Sanada Teşekkürler Berkay. Emeğine Sağlık.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst