Solved

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

Posted on 2010-08-14
10
1,292 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
Comment Utility
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
Comment Utility
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
Comment Utility
Oh - the bit that's failing is:

msg = im.Convert(imstr)
0
 

Author Comment

by:Computer_Dilo
Comment Utility
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
Comment Utility
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
Get up to 2TB FREE CLOUD per backup license!

An exclusive Black Friday offer just for Expert Exchange audience! Buy any of our top-rated backup solutions & get up to 2TB free cloud per system! Perform local & cloud backup in the same step, and restore instantly—anytime, anywhere. Grab this deal now before it disappears!

 

Author Comment

by:Computer_Dilo
Comment Utility
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
Comment Utility
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
Comment Utility
Props for comments
0
 
LVL 84
Comment Utility
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
Comment Utility
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

In the previous article, Using a Critera Form to Filter Records (http://www.experts-exchange.com/A_6069.html), the form was basically a data container storing user input, which queries and other database objects could read. The form had to remain op…
Introduction When developing Access applications, often we need to know whether an object exists.  This article presents a quick and reliable routine to determine if an object exists without that object being opened. If you wanted to inspect/ite…
Familiarize people with the process of utilizing SQL Server stored procedures from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Micr…
In Microsoft Access, learn different ways of passing a string value within a string argument. Also learn what a “Type Mis-match” error is about.

772 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now