diff --git a/README.md b/README.md index f48bd576..1a6fa09a 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,7 @@ To smooth over cross-platform compatibility, functionality that you won't find i ### Bitmap * The `Bitmap` class has one additional property: `raw_data` gets and sets the raw pixel data of a Bitmap in the form of a string. The string must be the size of the bitmap's `width*height*4`. If it is not, no error is raised, but the Bitmap will not be updated. +* The `Bitmap` class has one additional function: `to_file(path)` will save the bitmap to `path` in BMP format. This won't take opacity into account. ### Audio diff --git a/binding/bitmap-binding.cpp b/binding/bitmap-binding.cpp index 3e6cfef6..7f9bfaaa 100644 --- a/binding/bitmap-binding.cpp +++ b/binding/bitmap-binding.cpp @@ -445,6 +445,25 @@ RB_METHOD(bitmapSetRawData) return self; } +RB_METHOD(bitmapSaveToFile) +{ + RB_UNUSED_PARAM; + + VALUE str; + rb_scan_args(argc, argv, "1", &str); + SafeStringValue(str); + + Bitmap *b = getPrivateData(self); + + try { + b->saveToFile(RSTRING_PTR(str)); + } catch (const Exception &e) { + raiseRbExc(e); + } + + return RUBY_Qnil; +} + RB_METHOD(bitmapInitializeCopy) { rb_check_argc(argc, 1); @@ -496,6 +515,7 @@ bitmapBindingInit() _rb_define_method(klass, "raw_data", bitmapGetRawData); _rb_define_method(klass, "raw_data=", bitmapSetRawData); + _rb_define_method(klass, "to_file", bitmapSaveToFile); _rb_define_method(klass, "gradient_fill_rect", bitmapGradientFillRect); _rb_define_method(klass, "clear_rect", bitmapClearRect); diff --git a/src/bitmap.cpp b/src/bitmap.cpp index 15ea4991..266af4a8 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -883,9 +883,9 @@ void Bitmap::setPixel(int x, int y, const Color &color) p->onModified(false); } -void Bitmap::getRaw(void *output, int output_size) +bool Bitmap::getRaw(void *output, int output_size) { - if (output_size != width()*height()*4) return; + if (output_size != width()*height()*4) return false; guardDisposed(); @@ -893,6 +893,7 @@ void Bitmap::getRaw(void *output, int output_size) FBO::bind(p->gl.fbo); glReadPixels(0,0,width(),height(),GL_BGRA,GL_UNSIGNED_BYTE,output); + return true; } void Bitmap::replaceRaw(void *pixel_data, int size) @@ -919,6 +920,27 @@ void Bitmap::replaceRaw(void *pixel_data, int size) p->onModified(); } +void Bitmap::saveToFile(const char *filename) +{ + guardDisposed(); + + GUARD_MEGA; + + SDL_Surface *surf = SDL_CreateRGBSurface(0, width(), height(),p->format->BitsPerPixel, 0,0,0,0); + + if (!surf) + throw new Exception(Exception::SDLError, "Failed to save bitmap: %s", SDL_GetError()); + + getRaw(surf->pixels, surf->w * surf->h * 4); + + char *fn_normalized = shState->fileSystem().normalize(filename, 1, 1); + int rc = SDL_SaveBMP(surf, fn_normalized); + + SDL_FreeSurface(surf); + delete fn_normalized; + if (rc) throw new Exception(Exception::SDLError, "%s", SDL_GetError()); +} + void Bitmap::hueChange(int hue) { guardDisposed(); diff --git a/src/bitmap.h b/src/bitmap.h index 536d5bf1..687dc125 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -82,8 +82,9 @@ public: Color getPixel(int x, int y) const; void setPixel(int x, int y, const Color &color); - void getRaw(void *output, int output_size); + bool getRaw(void *output, int output_size); void replaceRaw(void *pixel_data, int size); + void saveToFile(const char *filename); void hueChange(int hue); diff --git a/src/graphics.cpp b/src/graphics.cpp index 28ec5447..1db4c280 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -984,9 +984,8 @@ void Graphics::screenshot(const char *filename) #ifdef __WIN32__ SDL_Surface *img = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0,0,0,0); - if (!img) throw Exception(Exception::SDLError, "%s", SDL_GetError()); + if (!img) throw new Exception(Exception::SDLError, "%s", SDL_GetError()); - glReadBuffer(GL_FRONT); glReadPixels(0,0,w,h,GL_BGRA,GL_UNSIGNED_BYTE, img->pixels); #else SDL_Surface *tmp, *img; @@ -999,7 +998,6 @@ void Graphics::screenshot(const char *filename) throw Exception(Exception::SDLError, "%s", SDL_GetError()); } - glReadBuffer(GL_FRONT); glReadPixels(0,0,w,h,GL_BGRA,GL_UNSIGNED_BYTE, tmp->pixels); for (int i = 0; i < h; i++) @@ -1016,7 +1014,7 @@ void Graphics::screenshot(const char *filename) SDL_FreeSurface(img); delete fn_normalized; - if (rc) throw Exception(Exception::SDLError, "%s", SDL_GetError()); + if (rc) throw new Exception(Exception::SDLError, "%s", SDL_GetError()); } DEF_ATTR_RD_SIMPLE(Graphics, Brightness, int, p->brightness)