Solved

Imagemagick via Access VBA not updating image file using convert or mogrify

Posted on 2010-08-14
10
1,315 Views
Last Modified: 2012-05-10
I have, after hours of torment, got Imagemagick to work inside Access VB code. I have an image displayed and a crop box can be set using the mouse along with brightness, contrast, sharpness and rotation controls all of which use the ImageMagickObject in VBA References.
When the code works its great but for some reason the same code which can crop and change the brightness wont work again after the first time. It seems I almost have to restart Access or to recompile to get it working again.
All I am doing is applying all the changes at once to an image file and saving it (via convert) to temp.jpg. Sometimes temp.jpg doesn't appear, sometimes it is the previous iteration and mogrify never seems to change it. If I take the array I am feeding convert/mogrify and feed it into the command line versions it works but in the code it runs without an error but does nothing.

Here's the code....

Private Sub SetPreviewImage(ChangePrev As Boolean)

Dim im As Object, imstr(), imcnt

    imcnt = 0
    If CropSp <> "" And Not ChangePrev Then
        ReDim Preserve imstr(imcnt + 1)
        imstr(imcnt) = "-crop " & CropSp
        imcnt = imcnt + 1
    End If
   
    If (Me.cbBright <> "0%" Or Me.cbContrast <> "0%") Then
        ReDim Preserve imstr(imcnt + 1)
        imstr(imcnt) = "-brightness-contrast " & Me.cbBright & "x" & Me.cbContrast
        imcnt = imcnt + 1
    End If

    If (Me.cbSharp.Column(1) <> "None") Then
        ReDim Preserve imstr(imcnt + 1)
        imstr(imcnt) = "-unsharp " & Me.cbSharp
        imcnt = imcnt + 1
    End If

    If (Me.cbRotate <> 0) Then
        ReDim Preserve imstr(imcnt + 1)
        imstr(imcnt) = "-rotate " & Me.cbRotate
        imcnt = imcnt + 1
    End If
   
    If imcnt > 0 Then
        Set im = CreateObject("ImageMagickObject.MagickImage.1")
       
        If ChangePrev Then
            ReDim Preserve imstr(imcnt + 1)
            imstr(imcnt) = MyAppPath & "pictures\temp.jpg"
            msg = im.Mogrify(imstr)
        Else
            ReDim Preserve imstr(imcnt + 2)
            imstr(imcnt) = MyAppPath & "pictures\" & Me.pic_newname
            imstr(imcnt + 1) = MyAppPath & "pictures\temp.jpg"
            msg = im.Convert(imstr)
        End If

        Set im = Nothing
       
    Else
        Me.bnPreview.Caption = "Preview"
   
    End If
   
    ShowPic (Me.pic_newname)
    Me.CropLine.Visible = False

Please save my sanity :( Imagemagick version is the latest released yesterday.
0
Comment
Question by:Computer_Dilo
  • 7
  • 3
10 Comments
 
LVL 84
ID: 33437415
You're in significantly uncharted territory <g>.

First, be clear that when using controls such as this (i.e. that were NEVER intended to be used in the VBA environment) you are on a very slippery slope. While it may work fine on your machine, and your wife's machine, my machine, etc etc there's no guarantee that it will work on all machines - or that it'll work on your machine tomorrow, after you update <some other program>. VBA is a much different environment than Visual Basic, and what works there doesn't always work in VBA.

That said: Exactly what code is failing? Where are you "cropping", for example?
0
 

Author Comment

by:Computer_Dilo
ID: 33440141
The "if" statements go..

1. Crop: calculated in the code which calls this sub from points clicked via mouse down and some calculations which work out where the top left and bottom right points would be in the pic - works fine (sometimes). CropSp contains the ?x?+?+? spec for the -crop option
2. Brightness/Contrast
3. Sharpness
4. Rotation

All of these (which have been selected or set) are placed in the array imstr which is fed to .convert or .mogrify depending on if its creating the temp.jpg or just altering it.

Actually come to think of it I'll have to just use convert all the time to get the actual change to the original image otherwise it wont be displaying what I actually want - doesn't matter - it still doesn't work sometimes but works others and I don't know why :(

This sub is called to create the temp.jpg file the first time using "convert" and then to change it as the brightness/contrast/sharpness/rotation combo boxes change when the preview image is displayed.
0
 

Author Comment

by:Computer_Dilo
ID: 33440143
Oh - the bit that's failing is:

msg = im.Convert(imstr)
0
Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

 

Author Comment

by:Computer_Dilo
ID: 33440406
Dammit stupid Access array references. It would appear if I redim as imcnt+1 I get an extra array slot which remains blank and wrecks the Convert call. So if I want to have an array of (1) I have to redim as (0) for instance. Like that makes any sense whatsoever.
0
 
LVL 84

Accepted Solution

by:
Scott McDaniel (Microsoft Access MVP - EE MVE ) earned 500 total points
ID: 33440688
Arrays have always been zero-based in VB/VBA unless you explicitly declare them as 1-based. Some languages use zero-based defaults, others use 1-based defaults.

Did that resolve your issue? You were just passing in an ill-formed array?
0
 

Author Comment

by:Computer_Dilo
ID: 33442467
Not entirely. It seems passing all the parameters at once is flakey. It does all the functions individually but not together reliably. I will be continuing to experiment and will post the solution here when I get it down. Any ImageMagick afficiandos who know how to get it to complain when there's a problem rather than silently doing nothing?

As to zero based arrays I am completely across them. But how sensible is it to dim an array as (0) when you want 1 element? Surely you would dim it as (1) but the reference would be (0)!?!?
0
 

Author Comment

by:Computer_Dilo
ID: 33442710
What an annoyingly useful open source beastie Imagemagick is >:(

OK - so the array input wasn't working so I split each function into a separate .convert or .mogrify (I checked in each function if another had already run convert and then ran mogrify on the temp image instead) and found a very useful thing....

Imagemagick is quite fussy about its input types - for instance the -rotate function requires an integer and the -sharpen function requires a string. Unless you have your im.convert(infile, "-rotate", deg, outfile) with "deg" being an interger then the convert will fail with an "illegal type" error.

I suspect when you feed it an array with the wrong types it just borks without the error!

So believe it or not I have a form which displays an image I can crop, brighten, contrast, sharpen and rotate on the fly with a discard changes button or a commit changes button which overwrites the original file with the changes. Pretty damn cool being able to manipulate images in Access itself :)
0
 

Author Closing Comment

by:Computer_Dilo
ID: 33442717
Props for comments
0
 
LVL 84
ID: 33444390
Any chance of posting a sample database with the control and code? This might be useful to others who are trying to do the same thing. While I can't imagine it would be used often - there's really not much call for image editing directly in Access - there are probably a fair number of people who might need to do this.
0
 

Author Comment

by:Computer_Dilo
ID: 33474113
I'll see how I go cutting it down to a sample database. I know others want to do this - everytime I searched for an answer over the past year I've found plenty of questions but no answers :)

I'll do it when I get a chance - might take a while.
0

Featured Post

Migrating Your Company's PCs

To keep pace with competitors, businesses must keep employees productive, and that means providing them with the latest technology. This document provides the tips and tricks you need to help you migrate an outdated PC fleet to new desktops, laptops, and tablets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Documents and settings folder 30 78
How do I assign a function with a parameter as the RowSource of a combo box? 9 43
User Level Security 6 38
Dcount help 2 12
This article is a continuation or rather an extension from Cascading Combos (http://www.experts-exchange.com/A_5949.html) and builds on examples developed in detail there. It should be understandable alone, but I recommend reading the previous artic…
Describes a method of obtaining an object variable to an already running instance of Microsoft Access so that it can be controlled via automation.
Learn how to number pages in an Access report over each group. Activate two pass printing by referencing the pages property: Add code to the Page Footers OnFormat event to capture the pages as there occur for each group. Use the pages property to …
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question