Skip to content

Commit

Permalink
Add Image.from_blob
Browse files Browse the repository at this point in the history
  • Loading branch information
Kjarrigan committed Mar 23, 2018
1 parent 14c1a74 commit 1049a13
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
9 changes: 9 additions & 0 deletions ext/gosu/gosu.i
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,15 @@ namespace Gosu
std::unique_ptr<Gosu::ImageData> image_data = $self->data().subimage(x, y, w, h);
return image_data.get() ? new Gosu::Image(std::move(image_data)) : nullptr;
}

%newobject from_blob;
static Gosu::Image* from_blob(const std::string& blob, int width, int height)
{
Gosu::Bitmap bitmap(width, height);
memcpy(bitmap.data(), &blob[0], width * height * 4);

return new Gosu::Image(bitmap);
}

%newobject from_text;
static Gosu::Image* from_text(const std::string& text, int font_height, VALUE options = 0)
Expand Down
12 changes: 12 additions & 0 deletions rdoc/gosu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,18 @@ def self.load_tiles(source, tile_width, tile_height, options = {}); end
# @return [Image?] an image that represents a portion of the containing image
def subimage(left, top, width, height); end

##
# Returns an image from a binary string of packed RGBA values. (e.g. from (Image#to_blob))
#
# @param blob [String] a string of any length (preferably width * height * 4)
# @param width [Ingeger] the width of the resulting image
# @param height [Integer] the height of the resulting image
#
# @return [Gosu::Image]
#
# @see Image#to_blob
def self.from_text(blob, width, height); end

# @!endgroup

# @!group Drawing an image
Expand Down
61 changes: 61 additions & 0 deletions src/RubyGosu.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2888,6 +2888,12 @@ SWIGINTERN Gosu::Image *Gosu_Image_subimage(Gosu::Image *self,int x,int y,int w,
std::unique_ptr<Gosu::ImageData> image_data = self->data().subimage(x, y, w, h);
return image_data.get() ? new Gosu::Image(std::move(image_data)) : nullptr;
}
SWIGINTERN Gosu::Image *Gosu_Image_from_blob(std::string const &blob,int width,int height){
Gosu::Bitmap bitmap(width, height);
memcpy(bitmap.data(), &blob[0], width * height * 4);

return new Gosu::Image(bitmap);
}
SWIGINTERN Gosu::Image *Gosu_Image_from_text(std::string const &text,int font_height,VALUE options=0){
std::string font = Gosu::default_font_name();
int width = 0;
Expand Down Expand Up @@ -7034,6 +7040,60 @@ _wrap_Image_subimage(int argc, VALUE *argv, VALUE self) {
}


SWIGINTERN VALUE
_wrap_Image_from_blob(int argc, VALUE *argv, VALUE self) {
std::string *arg1 = 0 ;
int arg2 ;
int arg3 ;
int res1 = SWIG_OLDOBJ ;
int val2 ;
int ecode2 = 0 ;
int val3 ;
int ecode3 = 0 ;
Gosu::Image *result = 0 ;
VALUE vresult = Qnil;

if ((argc < 3) || (argc > 3)) {
rb_raise(rb_eArgError, "wrong # of arguments(%d for 3)",argc); SWIG_fail;
}
{
std::string *ptr = (std::string *)0;
res1 = SWIG_AsPtr_std_string(argv[0], &ptr);
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "std::string const &","Gosu_Image_from_blob", 1, argv[0] ));
}
if (!ptr) {
SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "std::string const &","Gosu_Image_from_blob", 1, argv[0]));
}
arg1 = ptr;
}
ecode2 = SWIG_AsVal_int(argv[1], &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "int","Gosu_Image_from_blob", 2, argv[1] ));
}
arg2 = static_cast< int >(val2);
ecode3 = SWIG_AsVal_int(argv[2], &val3);
if (!SWIG_IsOK(ecode3)) {
SWIG_exception_fail(SWIG_ArgError(ecode3), Ruby_Format_TypeError( "", "int","Gosu_Image_from_blob", 3, argv[2] ));
}
arg3 = static_cast< int >(val3);
{
try {
result = (Gosu::Image *)Gosu_Image_from_blob((std::string const &)*arg1,arg2,arg3);
}
catch (const std::exception& e) {
SWIG_exception(SWIG_RuntimeError, e.what());
}
}
vresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Gosu__Image, SWIG_POINTER_OWN | 0 );
if (SWIG_IsNewObj(res1)) delete arg1;
return vresult;
fail:
if (SWIG_IsNewObj(res1)) delete arg1;
return Qnil;
}


SWIGINTERN VALUE
_wrap_Image_from_text(int argc, VALUE *argv, VALUE self) {
std::string *arg1 = 0 ;
Expand Down Expand Up @@ -11835,6 +11895,7 @@ SWIGEXPORT void Init_gosu(void) {
rb_define_method(SwigClassImage.klass, "draw_as_quad", VALUEFUNC(_wrap_Image_draw_as_quad), -1);
rb_define_method(SwigClassImage.klass, "gl_tex_info", VALUEFUNC(_wrap_Image_gl_tex_info), -1);
rb_define_method(SwigClassImage.klass, "subimage", VALUEFUNC(_wrap_Image_subimage), -1);
rb_define_singleton_method(SwigClassImage.klass, "from_blob", VALUEFUNC(_wrap_Image_from_blob), -1);
rb_define_singleton_method(SwigClassImage.klass, "from_text", VALUEFUNC(_wrap_Image_from_text), -1);
rb_define_singleton_method(SwigClassImage.klass, "load_tiles", VALUEFUNC(_wrap_Image_load_tiles), -1);
rb_define_method(SwigClassImage.klass, "to_blob", VALUEFUNC(_wrap_Image_to_blob), -1);
Expand Down
5 changes: 5 additions & 0 deletions test/test_image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ def test_subimage
assert_screenshot_matches win, 'trintrang.png'
end

def test_from_blob
img = Gosu::Image.new(media_path('triangle-25.bmp'))
assert_equal img.to_blob, Gosu::Image.from_blob(img.to_blob, 25, 25).to_blob
end

#----------- Drawing an image

def test_draw_with_opts
Expand Down

0 comments on commit 1049a13

Please sign in to comment.