Range.CopyPicture question

Gokhan Aycan

Active Member
Joined
Aug 8, 2021
Messages
460
Office Version
  1. 365
Platform
  1. Windows
Is there a limit on how many rows that can be copied or an image size limit? Or some other setting etc I need to check?

When the range is 6000 rows by 20 columns, the resulting image is around 1600 rows (just short of 25000 points).

Essentially using:

VBA Code:
rng.CopyPicture xlScreen, xlPicture

rng2.PasteSpecial

xlPrinter is even less, 200ish rows (I guess Print Area comes into play here).
xlBitmap has worse resolution and file size impact is almost double.
 

Excel Facts

Square and cube roots
The =SQRT(25) is a square root. For a cube root, use =125^(1/3). For a fourth root, use =625^(1/4).
So I was curious myself what the answer was, so I ran an API powered Range->JPG routine over the range A1:N500 (standard sizing) - no luck. GDI+ Error 7 which, depending on which Stackoverflow or Codeproject article you read, could be memory limit issues (entirely plausible on my current machine), an upper limit on height for GDI+ (possibly not?), or a result of poor coding (utterly inconceivable). Whatever it is, it didn't work.

So I tried
  • A1:A500 - Success - it produced a 24bit image 227w x 10000h - 96 dpi @1,605kb.
  • A1:A1000 - Fail
  • A1:A700 - Success - it produced a 24bit image 227w x 14000h - 96 dpi @2,331kb.
  • A1:A800 - Fail
Then I tried going width-ways, and attempted:
  • A1:T500 - Fail - which is an understatement. It started out innocently enough, displaying the standard error message. Then, all of the sudden - if you can visualise this - imagine the demonic possession of the child in the Exorcist - now take that, and reimagine it was a computer. It's been visually convulsing in the background the entire time I've been writing this post, and I'm too scared to see if its returned to normal. The flickering in the background seems to be less frequent, though...
It's back. And finally, because I'm a glutton for punishment:
  • A1:T200 - Success - 3271w x 4001h - 96dpi @9,598kb.
There is one more non-API image export method I'm aware of, but the output on that is a 32bit PNG and is always higher than 96dpi. Make of these results what you will - I should explain my (now demon-free) mini PC is 8gb ram - 1.8mhz - 64bit Excel / 64 bit Windows. I suspect other computers will fare better than mine did.

I know that this is probably an answer to a question you didn't ask, but I hope it's helpful in some way. :)
 
Upvote 0
Hey Dan,

Thanks for taking your time.

I have 16GB memory, maybe why I can get a larger range, idk. I can just copy in a loop for n number of rows, however, it is slow to do so (takes about 5-10 seconds) and tbh I can see it will not solve my real issue which I did not mention as it was not relevant when I asked the question.

Background: I am working on a charting app to create content for CloneHero (similar to GuitarHero/RockBand games). During playback I need to be able to scroll the worksheets and also keep them in sync with each other. There is also another workbook that is in charge of sample playback which runs on another instance. Apparently Excel was not made for this kind of thing and struggles.

It is kind of not possible to just write in words what I am trying to do, so here is a video of what I eventually want to achieve. In this one, I got rid of all shapes other than waveform shapes (9 of them per worksheet). It kind of works but still not good enough.

No Shapes Scrolling

Now, if I use Range.CopyPicture and just switch to another sheet, it gets much better however still doesn't satisfy what I am trying to achieve. Also, I needed to enable Hardware Acceleration which is not something I want to rely on. When it is off, I get hickups every 100 rows or so. You can see how it behaves in the video linked below (H.Accel. is enabled). Also, I set some samples to be played, yet they are not exactly tuned so kind of sounds off. So don't mind the drum sample sounds.

Scroll Test - Range.CopyPicture

Now (since last night), I am wondering if I can somehow pull this off w/o scrolling the rows at all but instead using GDI. However, I have no idea how that api works. My exposure to it is simply due to Jaafar Tribak's code for various tasks he posted in years.

Since I have no idea what I can do with GDI and how the performance would be, and not even knowing how to start (kind of), I have some questions reagrding that. These may be very noobish questions at this time, as I said I am not sure what can be achieved.

1 - Is it possible to merge images considering I would know the resulting size?
2- Would there be a size limit since the resulting image would be quite large (100,000 pixels high and more)?

For the song above each row is supposedly around 40 milliseconds. This can be as low as 5-10 milliseconds depending on the song.

I will ask a new question for the GDI part most likely.
 
Upvote 0
Thank you posting the videos - as you say, it's difficult to put into words, and the visuals really help understand what you're working on. It looks amazing, by the way. As to your questions:

1. it is possible to merge the sizes with GDI+, but you could even just use the WIA Com object (which I read is just a wrapper for the GDI+ API, but I could be wrong). I can try and find the code I found for that, if helpful.
2. From what I've read, that would exceed the limits for an image, but would it need to be a single image? My feeling is that once you've reach that kind of territory for a single image, you can't help but expect performance improvements.

In terms of GDI+, this is exactly what I've been trying to teach myself over the past few months, and while there is plenty out there for GDI and GDI+, it's a bit trickier and scarcer to find tutorials/information specifically for VBA, and moreover, already adjusted for 64bit! It's been time consuming, but as you say, it's mostly reverse engineering what Jaafar has very kindly produced, and trying to see how each of the pieces work. If you're interested, I can try compile a list of resources I've found to be helpful - there is an excellent tutorial on a French language site specifically for GDI+ for Excel VBA 32+64 bit. It's really good. (Google Chrome automatically translates it for me :) )

My (untrained and inexperienced) gut feeling is that you should be able to do those waveforms with GDI+ and I suspect that you could see improved performance.
To that end, when you've finished digesting all of Jaafar's work (or if you have already), you should check out the projects produced by The Trick (a VB6 programmer) - to a layperson such as myself, there seems to be a bit of overlap with what you're doing/interested in - namely, music, sound visualisation, vb and graphics (he uses GDI+). Perhaps the most relevant example can be see here with the video for his sound class, but there's also a audio spectrum visualiser, and a 8-bit retro music / audio synthesiser. The sound class in particular I know comes with an example project where it records sound and generates waveforms at runtime. It's a bit slow on my computer, but as we've already seen, my current system is a ridiculous benchmark, and so I'm sure it would run very smoothly on a system with 16gb ram! I would also add, looking at his code, he creates the graphics with a picturebox (which we annoyingly don't get in VBA) which I understand is slower than GDI+.

You may want to 'b u m p' this post to see if someone else has anything more helpful to contribute. I feel a bit bad about dragging your query out of the Unanswered threads section...
 
Upvote 0
Thanks for the info you provided. I will have to check them.

No, the image does not need to be 1 massive image, as long as I can scroll smoothly from start to end of a song.

I am using ffmpeg for some of the functions, like waveform and reading stream length (audio or video). Currently, I create a waveform png image for each 30 seconds, and then rotate them to be vertical. If it can be done more efficiently I will consider another method. Otherwise all playback features are done with mci sendstring commands. Since mci is old and can only play mp3 with default codecs, a real codec pack like k-lite is needed. I can also record using mci as long as Stereo Mix or similar is available. I also know about Bass.dll but didn't have any time to check if I could use it somehow.

If it is not a bother, I can use any links about the subject that you can provide.

I may DM Jaafar (although I know it is not a desired action) for his thoughts if he doesn't come across (I know from his own words that he spends his time with some of these things just for the challenge and to be better at it). I have used his mouse wheel scrolling, multipage background color bitmap idea (I re-worked the original multitab forms, so it is not used atm) and gave me some more ideas. I am sure there are others that may have experience with GDI here, I just don't have any names. And I have yet to actually start researching about GDI/+.

Don't worry about marking the question, it was not an advanced one anyway :) I will just ask a new, better formed one once I myself get some idea about the subject matter.
 
Upvote 0
Just an idea but would using Range.Copy and then insert picture work for you ?
 
Upvote 0
Hey Jaafar, thanks for dropping by.

I may try that as well when I next work on the project, but I have came to an understanding that scrolling rows will not be a solution. I either will need to copy some range as an image or somehow manage to do all the shapes, colors etc with gdi. Still unsure what I will be able to pull off if everything goes smoothly.

I have just starting working on the gdi stuff. May need help on that part whereever I can find it.
 
Upvote 0
Bingo - that's it. I will say that it talks about GDI+ in conceptual terms, etc, but note that they have created a (seemingly comprehensive) class module and what it covers in the tutorial expects that you'll be using that class. In addition to that, there a few focused game tutorials (Pacman), but make sure you download the Excel GDI+ examples workbook. I didn't see it until just the other week, and it's got some impressive working examples in there. There is also a GDI32 class, but no accompanying tutorial.

I have also recently come across a GDI+ focused site by a Japanese blogger (link) - it has a lot of examples of when / how to use it. I've really only just started looking at it, but it seems handy if for no other reason than there a plenty of samples to check out.

Also there is a room specifically for Games and Graphics programming over at VBForum, where people upload code / post tutorials for example: on how to use GDI+ to make sprites. (link)

You may also want to check out the PlanetSourceCode collection uploaded on to Github last year (I think) - it has the source code for countless VB projects. I've started working my way through them recently, trying to convert VB6 UserControls to to VBA classes, having managed to finish my first project the other day... baby steps...
1642860841087.png

Anyway, I hope that helps.
 
Upvote 0
Downloaded the class already, will download the example workbook also.

I will definitely check the other sites. Thanks for the info! :)

Indeed baby steps..
 
Upvote 0

Forum statistics

Threads
1,215,419
Messages
6,124,796
Members
449,189
Latest member
kristinh

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top