views:

153

answers:

4

Does anyone know how to use Win32's BitBlt() using Ruby? It seems like you need to use a destination DC (device context) and how can Ruby handle that? I use GetPixel() and it is really slow even to get 100 pixels (takes about 10 seconds). thanks.

+1  A: 

How about writing all of your image processing code in C++ as a Win32 executable and launching it as a separate process or calling into it from Ruby using the Win32API class? It makes sense to do it this way instead of writing a cludge in Ruby which will never perform as well.

Ed Swangren
that's ok except if it involves forking a new process every time you need to make a BitBlt() call, then the performance would not be so good. Also it will involves some kind of communication between processes to pass the bitmap back.
動靜能量
You have no clue as to what the performance would be like because you have not tested it. It entirely depends on your usage.
Ed Swangren
And I do not see a problem with communication between programs. It is a very common thing to do.
Ed Swangren
+1  A: 

I wouldn't go quite as far as Ed; chances are you only want to do some relatively simple and commonplace things that a normal GUI would do. For this, such libraries already exist and don't need to be written.

One example would be wxRuby.

I'm afraid I'm not familiar with it, but maybe it already offers some screen-grabbing utility methods.

Carl Smotricz
If the Ruby operation is taking 10 seconds it must be doing something that a 'normal' GUI would not do. That said, the OP does not tell us what they are actually trying to accomplish, so who knows.
Ed Swangren
Agreed, we're only speculating. But hey, there's not so much new under the sun: Whatever he wants to do has probably already been done, perhaps even in Ruby, or it's impossible or illegal (in which case it's definitely been done!). Let's see what further clues emerge! :)
Carl Smotricz
Yeah, I have never attempted to do any serious image processing in Ruby, so I am more prone to rely on something like C++ for that.
Ed Swangren
actually, i tried GetPixel using C some time ago and it was quite slow also... for example, if I get 100 pixels, i'd expect it to return immediately, but it won't, and if i SetPixel right after GetPixel, I actually see the SetPixel painting the pixels one by one. So even using C, GetPixel is slow too.
動靜能量
I haven't helped you much so far, time to stop futzing around. Here: <http://stackoverflow.com/questions/1678890/how-to-capture-a-part-of-a-screen-using-ruby-on-windows> is a similar question involving grabbing the whole screen. I suspect the cited method is much faster than trying to grab just 100 pixels singly. Good luck!
Carl Smotricz
What do you mean by "I used GetPixel in C"? There is no such method, so where are you getting this from? Also, I cannot imagine that it would take 10s to grab 100 pixels in *any* language, so the problem is in your code.
Ed Swangren
There is a GetPixel of some sort in Win32... http://msdn.microsoft.com/en-us/library/dd144909(VS.85).aspx i suspect some version of GetPixel actually takes a snapshot of the whole screen and then return you the pixel information. So that's why it is so slow.
動靜能量
+1  A: 

I'd just like to note that I'm seeing a similar thing. GetPixel is exceedingly slow on Vista. I've determined that this is the case when you're using that Aero thing. If you set desktop theme to one of the "Classic" settings, it's fast again. And the OP's estimate of ~10 seconds is not wrong, believe it or not. It's really exceedingly slow.

I, too, am looking for a BitBlt in Ruby. I expect I'll need to figure it out/write it, but was hoping someone else has already posted an example.

Bob
+1  A: 

Second Carl's other post: use win32 screenshot http://github.com/jarmo/win32screenshot

rogerdpack