I''d like to combine Wx (Wx::Image) with Rmagick/ImageMagick processing. Other than saving to disk constantly, how would I pass an Rmagick/ImageMagick image (e.g. RMagick:Image) to and from a Wx Image (e.g. Wx:Image)? -- Posted via http://www.ruby-forum.com/.
Pito Salas wrote:> I''d like to combine Wx (Wx::Image) with Rmagick/ImageMagick processing. > Other than saving to disk constantly, how would I pass an > Rmagick/ImageMagick image (e.g. RMagick:Image) to and from a Wx Image > (e.g. Wx:Image)? >If the image data from RMagick can be put into a string, you can use StringIO + Wx::Image.read and Wx::Image#write to exchange image data in a recognised format (PNG, TIF etc) in memory. See also Wx::Image#set_data for low-level access to raw image data (see the images/maths_drawing.rb for an example of using this). a
Hi, On Mon, Jun 1, 2009 at 9:17 PM, Alex Fenton <alex at pressure.to> wrote:> Pito Salas wrote: >> >> I''d like to combine Wx (Wx::Image) with Rmagick/ImageMagick processing. >> Other than saving to disk constantly, how would I pass an >> Rmagick/ImageMagick image (e.g. RMagick:Image) to and from a Wx Image >> (e.g. Wx:Image)? >> > > If the image data from RMagick can be put into a string, you can use > StringIO + Wx::Image.read and Wx::Image#write to exchange image data in a > recognised format (PNG, TIF etc) in memory. See also Wx::Image#set_data for > low-level access to raw image data (see the images/maths_drawing.rb for an > example of using this).I''m just about to add an RMagick sample to wxRuby. The following code snippet allows direct exchange between RMagick and wxRuby : magick_image = Magick::ImageList.new(img_file) # some magick conversion wx_image = Wx::Image.new(magick_image.columns, magick_image.rows) wx_image.set_data(magick_image.to_blob { self.format = "RGB" } The only problem is transparency. If img_file is a PNG file with transparent areas, those transparent areas are lost (i.e. displaying a Wx::Bitmap corresponding to the Wx::Image shows black areas instead of transparent areas). At the moment, the only way I found to keep the transparency is to save the magick_image into a PNG file and read it into a Wx::Image, but this is not what you''re looking for. Cheers. Chauk-Mean.
Chauk-Mean Proum wrote:> The only problem is transparency. > If img_file is a PNG file with transparent areas, those transparent > areas are lost (i.e. displaying a Wx::Bitmap corresponding to the > Wx::Image shows black areas instead of transparent areas). > > At the moment, the only way I found to keep the transparency is to > save the magick_image into a PNG file and read it into a Wx::Image, > but this is not what you''re looking for.Does Wx::Image#set_alpha help here? it works like set_data but for the alpha channel. a
On Wed, Jun 3, 2009 at 1:07 PM, Alex Fenton <alex at pressure.to> wrote:> Chauk-Mean Proum wrote: >> >> The only problem is transparency. >> If img_file is a PNG file with transparent areas, those transparent >> areas are lost (i.e. displaying a Wx::Bitmap corresponding to the >> Wx::Image shows black areas instead of transparent areas). >> >> At the moment, the only way I found to keep the transparency is to >> save the magick_image into a PNG file and read it into a Wx::Image, >> but this is not what you''re looking for. > > Does Wx::Image#set_alpha help here? it works like set_data but for the alpha > channel.Following Mario''s suggestion, I tried "RGBA" format which is available in RMagick. I extracted the image and the alpha raw data. But when I tried to use set_alpha with the alpha raw data, an exception is raised : alpha_raw_string = apha_raw_data.pack("C*") image.set_alpha(alpha_raw_string) It seems that there is a SWIG problem. Cheers. Chauk-Mean.
On Thu, Jun 4, 2009 at 2:54 AM, Mario Steele <mario at ruby-im.net> wrote:> On Wed, Jun 3, 2009 at 5:39 PM, Chauk-Mean Proum <chauk.mean at gmail.com> > wrote: >> >> On Wed, Jun 3, 2009 at 1:07 PM, Alex Fenton <alex at pressure.to> wrote: >> > Chauk-Mean Proum wrote: >> > >> > Does Wx::Image#set_alpha help here? it works like set_data but for the >> > alpha >> > channel. >> >> Following Mario''s suggestion, I tried "RGBA" format which is available >> in RMagick. >> I extracted the image and the alpha raw data. > > I just want to clarify, that you separated the RGB and the A values from > each pixel byte section (As I call it) in the blob that is returned from > RMagick, and tried applying it via image.set_data, and image.set_alpha,Yes. Here is the detailed code I''m using : wx_image = Wx::Image.new(magick_image.columns, magick_image.rows) rgba_data = magick_image.to_blob { self.format = "RGBA" } rgba_array = rgba_data.unpack("C*") # separate the RGB image and the alpha data i = 0 image_array, alpha_array = rgba_array.partition do |val| i += 1 if i % 4 != 0 true else false end end image_data = image_array.pack("C*") alpha_data = alpha_array.pack("C*") wx_image.data = image_data wx_image.set_alpha(alpha_data) The set_alpha method raises the following exception : rmagic_bitmap_image.rb:109:in `set_alpha'': Wrong arguments for overloaded method ''wxImage.SetAlpha''. (ArgumentError) Possible C/C++ prototypes are: void wxImage.SetAlpha(unsigned char *alpha, bool static_data) void wxImage.SetAlpha(int x, int y, unsigned char alpha) Chauk-Mean.
Hi Mario, On Thu, Jun 4, 2009 at 9:37 PM, Mario Steele<mario at ruby-im.net> wrote:> > Alright, this may be a mistake in the Documentation, but try doing: > wx_image.set_alpha(alpha_data, false)I''ve already tried that with the true value :-) and it didn''t work.> Something tells me that SWIG isn''t taking into consideration the default > param for static_data.Yes, there is a SWIG problem here. I don''t know what but this can be revealed simply with the following code (there is no need to have RMagick) : require ''wx'' wx_image = Wx::Image.new(2,2) image_data = [0,0,0,64,64,64,128,128,128,255,255,255].pack("C*") alpha_data = [0,255,0,255].pack("C*") unique_alpha_data = [255].pack("C") wx_image.set_data(image_data) #Following call works : wx_image.set_alpha() #Following calls do not work : #wx_image.set_alpha(alpha_data) #wx_image.set_alpha(alpha_data, false) #wx_image.set_alpha(0,0,unique_alpha_data) I''m not sufficiently comfortable with SWIG to fix such kind of issue. Cheers. Chauk-Mean.
Hi all, On Thu, Jun 4, 2009 at 11:57 PM, Chauk-Mean Proum<chauk.mean at gmail.com> wrote:> Yes, there is a SWIG problem here. I don''t know what but this can be > revealed simply with the following code (there is no need to have > RMagick) : > ... > > #Following call works : > wx_image.set_alpha() > > #Following calls do not work : > #wx_image.set_alpha(alpha_data) > #wx_image.set_alpha(alpha_data, false) > #wx_image.set_alpha(0,0,unique_alpha_data) > > I''m not sufficiently comfortable with SWIG to fix such kind of issue.I''ve finally been able to fix this SWIG issue which seems to be caused by : - the use of a typemap for the first form of the SetAlpha C++ method - and by the fact that this SetAlpha C++ method has an overloaded method I''ve just hidden the overloaded method in the SWIG header for the Image class and now everything works. Maybe Alex will be able to provide a complete fix to this issue without having to hide the overloaded method. I''ve also found a way to get directly the alpha raw data from a RMagick image. So here is the code to convert seamlessly a RMagick image to a wxRuby image : wx_img = Wx::Image.new(magick_img.columns, magick_img.rows) # Set the image data wx_img.data = magick_img.to_blob { self.format = "RGB" } # Set the alpha (transparency) if any if magick_img.alpha? wx_img.alpha = magick_img.to_blob { self.format = "A" } end I''ve just committed the fix and a complete sample (samples/drawing/rmagic_bitmap_image.rb) in subversion. Cheers. Chauk-Mean.
Hi [switched to wxruby-dev] Chauk-Mean Proum wrote:> I''ve finally been able to fix this SWIG issue which seems to be caused by : > - the use of a typemap for the first form of the SetAlpha C++ method > - and by the fact that this SetAlpha C++ method has an overloaded method > > I''ve just hidden the overloaded method in the SWIG header for the > Image class and now everything works. > Maybe Alex will be able to provide a complete fix to this issue > without having to hide the overloaded method. >Good job on the SWIG fix for set_alpha. Re the one that we can''t fix - I think this is one where C++ overloading is used in a stupid way, so that two methods that do different things have the same name with different signatures. The enabled one sets all alpha data at the same time (analogous to set_data), the other sets it for a single pixel (analogous to set_rgb). I suggest that we use a SWIG %rename here to avoid the collision, as the C++ types are hard to distinguish in Ruby. I''m not sure what the names should be: set_alpha_data / set_alpha is more consistent with set_data / set_rgb set_alpha / set_pixel_alpha is more like what the sample and current docs describe Chauk-Mean, you''ve led the work on this so it''s up to you. Whichever we add we may want to add aliases to have a consistent set of alpha / rgb methods: set_alpha_data / set_alpha / set_rgb_data / set_rgb set_data / set_pixel / set_alpha_data / set_alpha_pixel alex