ImageMagick

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)?

Pito S. 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 F. [email protected] wrote:

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.

I dunno, in RMagick, is the format “RGBA” available? If it is, that
should
allow for transparencies to be retained. Just a thought, don’t have
RMagick
to test.

Chauk-Mean P. 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 F. [email protected] 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.

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 S. [email protected] wrote:

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.

On Thu, Jun 4, 2009 at 6:45 AM, Chauk-Mean P.
[email protected]wrote:

wx_image.data = image_data
wx_image.set_alpha(alpha_data)

Alright, this may be a mistake in the Documentation, but try doing:
wx_image.set_alpha(alpha_data, false)

Something tells me that SWIG isn’t taking into consideration the default
param for static_data.

On Wed, Jun 3, 2009 at 5:39 PM, Chauk-Mean P.
[email protected]wrote:

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.

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,
or
did you just tried to do the entire image data blob set through
image.set_alpha?

I just want to make sure, there’s no confusion about the order that is
going
on, with this.

Hi Mario,

On Thu, Jun 4, 2009 at 9:37 PM, Mario S.[email protected] 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 :slight_smile: 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 P.[email protected]
wrote:

#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.