Visual Basic Wiki
Advertisement

Firstly, make sure you have ImageMagick installed, and that you registered the COM interface during installation. If you want to edit PDF's, you MUST install ghost script as ImageMagick shells out part of the work to that.

https://www.ghostscript.com/

Add the reference to the project[]

Select References from the Tools menu. Select the ‘ImageMagickObject 1.0 Type Library’.

Create the object[]

The object is called MagickImage, and you can instantiate it with New, e.g.:

Dim VarName As New MagickImage

Call methods on the object[]

The methods of this object work exactly like the command line utilities that come with ImageMagick, so

convert source -resize 1280x1024^ -extent 1280x1024 destination

becomes

VarName.Convert Source, "-resize", "1280x1024^", "-extent", "1280x1024", Destination

where Source and Destination are variables containing the filenames of the source and destination image.

Alternate example, submitted and tested on 12/12/2019 in Excel using VBA:

Sub ConvertPdf()
Dim Source As String
Dim Destination As String
Source = ThisWorkbook.Path & "\ExampleFile.PDF"
Destination = ThisWorkbook.Path & "\ConvertedFile.JPG"
Set img = CreateObject("ImageMagickObject.MagickImage.1")
img.Convert "-density", "600", Source, Destination 
End Sub

Safety[]

I've found that enclosing the Convert call with the following statements helps to prevent accidentally overwriting the source image in case you mix up the parameters in the call:

Open Source For Binary Access Read Lock Write As #FileNum
'Convert call here.
Close #FileNum

I don't know if this depends on your Windows/service pack version, so I wouldn't depend on it, but it can't hurt.

I tested this using the following code:

Dim I As New MagickImage
Open "C:\dst.bmp" For Binary Access Read Lock Write As #1
Text1 = I.Convert("C:\src.bmp", "-resize", "64x64", "C:\dst.bmp")
Text2 = I.Convert("C:\src.bmp", "-resize", "64x64", "C:\dst2.bmp")
Close #1

Even though both calls seemed to succeed (both text boxes contained ‘64,40,BMP’) the file dst.bmp was untouched, while dst2.bmp contained a thumbnail version of src.bmp.

Performance[]

If there's a chance that you're going to convert large images, you have got to realize that by default ImageMagick tries to load the entire image in standard memory. This can be disastrous for performance. Why? Well suppose as a simplified example that your memory contains the following:

0MB     32MB    64MB    96MB    128MB   160MB   192MB   224MB   256MB
[ Explorer ][ Browser ][ MP3 ][ Newsreader ][ Anti-virus ][ VB ]

Suppose that you now read in an image of 6000x4500 pixels. That's 27 megapixels. On read-in it will be converted to a bitmap, probably (actually this depends on how ImageMagick was configured during compilation) 16 bits per channel RGB, or around 154 MB. After a lot of disk trashing, your memory probably looks like this:

[           Your huge image           ][er ][ Anti-virus ][ VB ]

Of course, these may not be the actually processes that get clobbered, but you'll see that doesn't really matter. Because now the sound card wants the next bit of data. More HDD noise.

[           Your huge image           ][ MP3 ][Anti-virus][ VB ]

It's taking a while, you decide to do something else. Let's read the news. You click the taskbar icon of your newsreader. *grrcntl whirr whirr crackly frrfgrgrgfgrff*

[           Your huge image           ][ MP3 ][ Explorer ][ VB ]
[ Newsreader ][    Your huge image    ][ MP3 ][ Explorer ][ VB ]

Wait! I was using those pixels! *tortured hard drive sounds here*

[ News][           Your huge image           ][ Explorer ][ VB ]

Sound card buffer's empty again. That news article looks interesting, let's open the full version.

[ MP3 ][ Browser ][ Your image ][ Newsreader ][ Explorer ][ VB ]

I told you I was using those pixels! Get your grubby paws off 'm! *more walking on gravel*

[ MP3 ][ Browser ][  Your ...  ][ News][  ... huge image       ]

Oh wait, that's actually the code I'm running. Taskbar button for browser is repainted in the pressed state. *bzzgrrfrqtrgfrgg*

[ Explorer ][ VB ][  Your ...  ][ News][  ... huge image       ]

Browser window opens, sound buffer is empty again. *hhgrrgffrfrdhhrqrwrwqgr*

[ Explorer ][ VB ][ Browser ][ MP3 ][s][  ... huge image       ]

What happened to my pixels? I need them, now! ... and so on, and so forth...

End result: the system slows to a crawl, and neither you nor ImageMagick are getting any work done. To prevent this horrible scenario, insert the following before all other arguments to Convert:

"-limit", "memory", "8mb", 

This way, you limit how much memory ImageMagick will use. Yes, it will be slower to use disk storage more than memory (much slower in fact, about 1000x as slow) but not nearly as slow as the above scenario and best of all, you can still use your computer. The documentation says that you might also want to consider decreasing the map limit, but I haven't found that to be necessary.

Of course, if the ideal value should be 8MB depends highly on the situation. Things to consider are that if the image data fits in the limit, processing will, as noted, be much faster. But higher limits will slow down your computer. Maybe it's a background process? Or on the contrary, an interactive one? How much memory is installed? All things to think about when choosing a suitable memory limit.

Advertisement