bool Image::SaveJPG(const String & fileName, int quality) { FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem && !fileSystem->CheckAccess(GetPath(fileName))) { LOGERROR("Access denied to " + fileName); return false; } if (IsCompressed()) { LOGERROR("Can not save compressed image to JPG"); return false; } if (data_) return jo_write_jpg(fileName.CString(), data_.Get(), width_, height_, components_, quality) != 0; else return false; }
bool _imageFile::writeBitmap( const _bitmap& source , _optValue<_mimeType> mimeType2write , _optValue<_imageFileCompression> compression ) { if( !source.isValid() ) return false; bool result = false; _mimeType mime = mimeType2write.isValid() ? (_mimeType)mimeType2write : this->getRealMime(); // If file doesn't exist already, create it! this->create(); switch( mime ) { case _mime::image_bmp: GenericBMPEncoder::encode( this->getFileName().c_str() , source.getWidth() , source.getHeight() , source.getBitmap() ); break; case _mime::image_png: { YsRawPngEncoder* encoder = new YsRawPngEncoder(); if( compression.isValid() && (_imageFileCompression)compression == _imageFileCompression::none ) encoder->SetDontCompress(1); _u32 numberPixels = source.getWidth()*source.getHeight(); _u8* buffer = new _u8[numberPixels*4]; _u8* tempBuffer = buffer; _pixelArray data = source.getBitmap(); do { _color col = _color(*data++); tempBuffer[0] = col.getR()<<3; tempBuffer[1] = col.getG()<<3; tempBuffer[2] = col.getB()<<3; tempBuffer[3] = col.getAlpha()<<7; // Expand 1bit Alpha to 8bits tempBuffer+=4; } while( --numberPixels > 0 ); result = encoder->EncodeToFile( this->getFileName().c_str() , source.getWidth() , source.getHeight() , 8 /*8bit per Channel*/, 6 /*True-Color with Alpha*/ , buffer ); delete[] buffer; delete encoder; break; } case _mime::image_gif: { // Create palette with 256 entries _colorPalette palette = _colorPalette::fromBitmap( source ); palette.downsample( 256 ); // Open File for writing FILE* file = fopen( this->getFileName().c_str() , "wb+" ); // Get Colors in the palette _vector<_color> colors = palette.getColors(); _s16 transparentIndex = palette.hasTransparentColor() ? colors.size() - 1 : -1; // Predefines... _u16 numColors = colors.size(); _u32 numPixels = source.getWidth()*source.getHeight(); _u8* paletteBuffer = new _u8[numColors*3]; _u8* imageBuffer = new _u8[numPixels]; // Convert palette to _u8[3] for( int i = 0 ; i < numColors ; i++ ) { _color col = colors[i]; paletteBuffer[i*3+0] = col.getR()<<3; paletteBuffer[i*3+1] = col.getG()<<3; paletteBuffer[i*3+2] = col.getB()<<3; } // Convert image to indexed format _pixelArray data = source.getBitmap(); for( _u32 i = 0 ; i < numPixels; i++ ) imageBuffer[i] = palette.getClosestColor(*data++); // Save gif! result = gif_write( file , imageBuffer , source.getWidth() , source.getHeight() , paletteBuffer , numColors , transparentIndex ); delete[] paletteBuffer; delete[] imageBuffer; fclose( file ); break; } case _mime::image_jpeg: { _u32 numberPixels = source.getWidth()*source.getHeight(); _u8* buffer = new _u8[numberPixels*3]; _u8* tempBuffer = buffer; _pixelArray data = source.getBitmap(); do { _color col = _color(*data++); tempBuffer[0] = col.getR()<<3; tempBuffer[1] = col.getG()<<3; tempBuffer[2] = col.getB()<<3; tempBuffer += 3; } while( --numberPixels > 0 ); int quality = compression.isValid() ? (int)(_imageFileCompression)compression : 90; // Set Quality result = jo_write_jpg( this->getFileName().c_str() , buffer , source.getWidth() , source.getHeight() , 3 , quality ); delete[] buffer; } default: break; } return result; }