diff --git a/cocos/platform/CCImage.cpp b/cocos/platform/CCImage.cpp index 03f6ab82a0..83264e7438 100644 --- a/cocos/platform/CCImage.cpp +++ b/cocos/platform/CCImage.cpp @@ -880,12 +880,45 @@ bool Image::decodeWithWIC(const unsigned char *data, ssize_t dataLen) bool Image::encodeWithWIC(const std::string& filePath, bool isToRGB, GUID containerFormat) { - WICPixelFormatGUID format = isToRGB ? GUID_WICPixelFormat24bppRGB : GUID_WICPixelFormat32bppRGBA; + // Save formats supported by WIC + WICPixelFormatGUID targetFormat = isToRGB ? GUID_WICPixelFormat24bppBGR : GUID_WICPixelFormat32bppBGRA; + unsigned char *pSaveData = nullptr; + int saveLen = _dataLen; + int bpp = 4; - WICImageLoader img; - return img.encodeImageData(filePath, _data, _dataLen, format, _width, _height, containerFormat); + if (targetFormat == GUID_WICPixelFormat24bppBGR && _renderFormat == Texture2D::PixelFormat::RGBA8888) + { + bpp = 3; + saveLen = _width * _height * bpp; + pSaveData = new unsigned char[saveLen]; + int indL = 0, indR = 0; + + while (indL < saveLen && indR < _dataLen) + { + memcpy(&pSaveData[indL], &_data[indR], 3); + indL += 3; + indR += 4; + } + } + else + { + pSaveData = new unsigned char[saveLen]; + memcpy(pSaveData, _data, saveLen); + } + + for (int ind = 2; ind < saveLen; ind += bpp) { + std::swap(pSaveData[ind - 2], pSaveData[ind]); + } + + bool bRet = false; + WICImageLoader img; + bRet = img.encodeImageData(filePath, pSaveData, saveLen, targetFormat, _width, _height, containerFormat); + + delete[] pSaveData; + return bRet; } + #endif //CC_USE_WIC bool Image::initWithJpgData(const unsigned char * data, ssize_t dataLen) diff --git a/cocos/platform/winrt/WICImageLoader-win.cpp b/cocos/platform/winrt/WICImageLoader-win.cpp index a9ec577598..ac7c42c4a8 100644 --- a/cocos/platform/winrt/WICImageLoader-win.cpp +++ b/cocos/platform/winrt/WICImageLoader-win.cpp @@ -325,23 +325,21 @@ WICPixelFormatGUID WICImageLoader::getPixelFormat() return _format; } -bool WICImageLoader::encodeImageData(std::string path, ImageBlob data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat) +bool WICImageLoader::encodeImageData(std::string path, const unsigned char* data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat) { assert(data != NULL); assert(dataLen > 0 && width > 0 && height > 0); IWICImagingFactory* pFact = getWICFactory(); - HRESULT hr = S_FALSE; + HRESULT hr = E_FAIL; IWICStream* pStream = NULL; - if(NULL != pFact) - { + if (NULL != pFact) { hr = pFact->CreateStream(&pStream); } - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { std::wstring wpath; wpath.assign(path.begin(), path.end()); hr = pStream->InitializeFromFilename(wpath.c_str(), GENERIC_WRITE); @@ -349,54 +347,50 @@ bool WICImageLoader::encodeImageData(std::string path, ImageBlob data, size_t da IWICBitmapEncoder* pEnc = NULL; - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = pFact->CreateEncoder(containerFormat, NULL, &pEnc); } - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = pEnc->Initialize(pStream, WICBitmapEncoderNoCache); } IWICBitmapFrameEncode* pFrame = NULL; IPropertyBag2* pProp = NULL; - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = pEnc->CreateNewFrame(&pFrame, &pProp); } - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = pFrame->Initialize(pProp); } - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = pFrame->SetSize(width, height); } - if(SUCCEEDED(hr)) - { - hr = pFrame->SetPixelFormat(&pixelFormat); + if (SUCCEEDED(hr)) { + WICPixelFormatGUID targetFormat = pixelFormat; + hr = pFrame->SetPixelFormat(&targetFormat); + + if (targetFormat != pixelFormat) { + hr = E_INVALIDARG; + } } - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { size_t bpp = getBitsPerPixel(pixelFormat); size_t stride = (width * bpp + 7) / 8; hr = pFrame->WritePixels(height, stride, dataLen, (BYTE*)data); } - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = pFrame->Commit(); } - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = pEnc->Commit(); } diff --git a/cocos/platform/winrt/WICImageLoader-win.h b/cocos/platform/winrt/WICImageLoader-win.h index ad16eada36..4834c75f74 100644 --- a/cocos/platform/winrt/WICImageLoader-win.h +++ b/cocos/platform/winrt/WICImageLoader-win.h @@ -59,7 +59,7 @@ public: WICPixelFormatGUID getPixelFormat(); int getImageData(ImageBlob rawData, size_t dataLen); bool decodeImageData(ImageBlob data, size_t dataLen); - bool encodeImageData(std::string path, ImageBlob data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat); + bool encodeImageData(std::string path, const unsigned char* data, size_t dataLen, WICPixelFormatGUID pixelFormat, int width, int height, GUID containerFormat); protected: bool processImage(IWICBitmapDecoder* decoder);