Link to home
Start Free TrialLog in
Avatar of chovis78
chovis78

asked on

Resize Pictures in Access

Is it possible to resize pictures that are in the attachment data type in Access 2007 automatically by code?
Avatar of Boyd (HiTechCoach) Trimmell, Microsoft Access MVP 2010-2015
Boyd (HiTechCoach) Trimmell, Microsoft Access MVP 2010-2015
Flag of United States of America image

AFAIk you will have to:
1)  export the attachment to a folder
2) call some external app that can do the resize
3) import the file back in as an attachment.

What software will you be using to resize the image? Can it be automated or had a command line interface?
Avatar of chovis78
chovis78

ASKER

I have the exporting attachments to a folder done, and right now i am using Total Image converter to resize but can use whatever. And yes right now i hae to manually resize them right now would not like to if i dont have to and the importing back as an attachment is the biggest issue, in that i cant.
Does Total Image converter support running via a command line  (no user interaction)?

About working with the attachment data type:
A friend and fellow Access MVP has a great tutorial on the subject here:
Microsoft® Access 2007 Working with the Attachment Data Type

Personally I avoid the attachment data type.

Curious, why are you needing to resize the images?
This is yet another reason why most developers do not store images IN the DB. (They link to them)

Resizing a linked image is a simple matter of using the SizeMode Property of an image control, and resizing the control.

Both of which can be done via code
You will have to clearly define what you mean by: "Resize "

Is your ultimate goal to resize the image File itself, or simply resize the image in Access for display purposes (in a form or Report)?

To simply resize the image in Access for display purposes (in a form or Report), try something like this:

Access-BasicLinkOpenImageDialogB.mdb
<You will have to clearly define what you mean by: "Resize ">
I'm with that, @boag2000
I have extensive experience and code for mucking with images.
Try getting 120+ digital photos on an Access report and then printing it :)

I have code that knocks images down to size as they go into storage, and as they come out to go on the report.
Have a look here
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a332a77a-01b8-4de6-91c2-b7ea32537e29


It turns out that Access 2003 prints photos at 96 dpi.  Trying to print photos taken at, like 4000 x 3000 by idiot engineers, in controls that are 2" x 1.5" breaks the report in a hurry.
Resizing them to something reasonable BEFORE they hit the report works very well.

Like everyone else, I DON'T put the images in the db, I put them in a folder, and just a pointer in the database.

Let us know what your resizing needs are.
Am I missing somehting here. This was just a download of a dll. Do you actually have code? I am trying to reduce the size of the image when it is put into the db. Like if someone uploads a 2mb file i want to automatically reduce that file to 250kb or something like that. I understand the linking to files but this is the way this db is setup and already has tons of picutres so i wouldnt know how to extract those pictures and link them back to the correct record in the db without manually having to do that. Unless you do.
<<I am trying to reduce the size of the image when it is put into the db. Like if someone uploads a 2mb file i want to automatically reduce that file to 250kb or something like that. >>

Are you controlling the way the user attaches the file with a custom form and VBA code?  

About storing externally:
You stated you already have the exporting attachments to a folder done. As you export each one you could have your VBA code store the path.  I use this method: Document Links or Document Links 2


 
Are you controlling the way the user attaches the file with a custom form and VBA code?

No they are just using the attachment data type in 2007.

Correct I can export the attachments to a folder but I dont know how to reference those attachments with a record id within the main table, they just all export with the attachement name.
<Correct I can export the attachments to a folder but I dont know how to reference those attachments with a record id within the main table, they just all export with the attachement name. >

How does this apply to your question here of "resizing pictures"
You still have not made it clear what you mean by this, despite two experts asking for details...

Can you please take a minute to clarify this point please?
If you read my comment above i said I am trying to reduce the size of the image when it is put into the db. Like if someone uploads a 2mb file i want to automatically reduce that file to 250kb or something like that.  Exporting the attachments and referencing them was talking about another topic that got brought into this conversation. So yes i did clarify myself.
<Do you actually have code?>
Yes, I have code.
My users jack in a digital camera, and set off an 'add the pictures routine'
If the camera reports as a drive letter (yay!) a filedialog and filesystemobject routine lets them select images.
If the camera reports as a camera device (boo!) a spearate VBScript and Access VBA routine lets them select images.

The images get evaluated for sizes as they are being saved.  If they are larger than 1600 x 1200, the originals get saved in a subfolder "Large"
They are resized on the fly down to 1600 x 1200 and saved in a folder.
A Primary key, a foreign key and a path to the picture get written to a table

When a report gets requested, the 1600 x 1200 pictures get resized down on the fly to something close to what Access will print them at (96 dpi x control height and width) and stuffed in a temporary folder and then embedded in the report, which renders, previews and prints.

Before I started with this 7 or 8 4000 x 3000 pictures and 15 or so 1600 x 1200 pictures were all I could make Access cram into 2 X 1.5 image controls.  The report would just print whitespace where the pictures were supposed to be.

Needless to say, there is a LOT of code.
While I could just dump 1500 lines or so, and let you pick through the wreckage for what YOU need, that's a little sloppy.
So I'd like to know what your needs are and what your mechanisms for saving the pictures are.
My guys select them through a filedialog or a WIA.CommomDialog, so there are events to integrate the resizing with.

I pointed you at the WIA site because my code depends on that dll being in place.  It's free.  It works well.  It's well documented.  But you have to have it in place before anything I post will do you any good.

You could post a related question that asks how to replace an attachment field with a folder and a related table.  The related table is simple enough.  An autonumber primary key, a number field to store the primary key of the table that now has the attachment field, and a text field to store the path to the exported file.  The nuts and bolts of writing a routine to export the attachment and populate the new table isn't something I can do for you at the moment, because the unit I'm on is running Access 2003--no attachments.

So, how this needs to get done is up to you.  Do you want to change how your users do the pictures?  Do you want to go to a folder-and-pointer storage method?
Do you want a maintenance routine that spits out your attachment, deletes it from the db, and then pulls it back in much smaller and cleans up?

You have a bunch of options.  I have code.  But I can't read your mind :)
Thanks for the reply. First think i would like to try is the maintenance routine that spits out the attachment, deletes it from the db, and then pulls it back in much smaller and cleans up. If that doesnt work i would have to go to the folder and pointer storage method. But as you stated you have 2003, so will your code work with mine since I am using attachments and i assuming your using OLE.
chovis78,

Nick67 said:
<<Like everyone else, I DON'T put the images in the db, I put them in a folder, and just a pointer in the database.>>

You said:
<<so will your code work with mine since I am using attachments and i assuming your using OLE.>>
No.  Nick67 does not store the images is the database. Most people don't.
An OLE object datatype is a different monster from an attachment datatype, and as everyone who has been around the Access block will tell you, neither one of them is a good idea.  I store the images in folders on the file system.  I store keys and paths in a table in the db.  Attachments, I don't do--at least not on this machine :)

But, you're up against it, and nothing is insurmountable, so I'll see what I can do.
<I have the exporting attachments to a folder done>

How did you do that?
Did you use code?
Post it.

That WIA link that I posted.  Did you download the DLL and register it and get it ready to go?
What i would really love to do is, export all the attachments to a folder and call each attachment the id number that is in that table. Then point them from the database to a folder. I do have the code i will post in a few.
Here is the code for extracting the attachments. I attached the db and the code in a text just in case you cant open the db.
Attachments.accdb
code.txt
Alright.

I can't open a accdb from Access 2003, and you can't change it to an mdb with attachments :)
No Matter, I've got the txt code.

Now.
The attachments are ALWAYS images?
And what size (width x height in pixels) do you want?
Yes they are always images. 448 x 336 is fine.
Ok,

GetOpenFile isn't something I use, but it is something I have.
I'll play with your stuff and get some code hashed out--but it's going to be a bit.

Work...I do have to do some :) and not just solve programming puzzles
No rush take your time, i appreciate any help.
Can you post your GetOpenFile function.
The code you posted earlier has it as a dependency
Only worry about the Public Sub ExtractAttachment i didnt mean to copy all of that. The only part i am using right now is the ExtractAttachment function. The other is not working quite yet.
Ok, Give this a whack.
You need the WIA DLL.
You need to set a reference to it (wiaaut.dll)

Will it go BANG off the bat?
Probably--but you've got something to start debugging

You'll need a folder at CurrentProject.Path & "\TempImages\"
You'll need a folder at CurrentProject.Path & "\small\"

You'll need a table, tblPictures

PictureID Long Autonumber
TheMainTablePrimaryKey  long
Path text(255)

Let me know how it goes
Public Sub ExtractAttachment(TableName As String, FieldName As String, Optional Criteria As Variant = Null)

    'Opens a recordset base on TableName, and extracts all attachments from field: FieldName
    'If no criteria string is provided, loops through all records in the table and extracts all of the attachments
    
    Dim rsMain As DAO.Recordset, rsAtt As DAO.Recordset
    Dim strSQL As String
    Dim strPath As String
    
        'Nick's stuff
        Dim rsPicPath As DAO.Recordset
        Set rsPicPath = CurrentDb.OpenRecordset("Select * from tblPictures where 1 = 2", dbOpenDynaset, dbSeeChanges)
        Dim strTempPath As String
        strPath = CurrentProject.Path & "\TempImages\" 'you'll have to create this
                          
        Dim filename As String
        'end Nick's stuff
    
    On Error GoTo ProcError
    
    strSQL = "SELECT * FROM [" & TableName & "]" & (" WHERE " + Criteria)
    strSQL = Replace(Replace(strSQL, "[[", "["), "]]", "]")
    Set rsMain = CurrentDb.OpenRecordset(strSQL, , dbFailOnError)
    
    'Select the folder to extract the files to
    strPath = CurrentProject.Path & "\"
    
    'Loop through the records
    Do While Not rsMain.EOF

        Set rsAtt = rsMain.Fields(FieldName).Value
        While Not rsAtt.EOF
            rsAtt.Fields("FileData").SaveToFile strTempPath
             'Ok we've saved out to a temp folder
             filename = rsAtt.Fields("FileData")
             'This is optional
             'now set a pointer
             With rsPicPath
                 .AddNew
                 !TheForeignKey = rsMain!ThePrimaryKey
                 !Path = strPath & "small\" & filename
                 .Update
             'Ok now call
                  Call ResizeAndReloadAttachment(strTempPath & filename, filename)
             End With
            'not doing this
            'rsAtt.Fields("FileData").SaveToFile strPath
            rsAtt.MoveNext
        Wend
        rsMain.MoveNext
    Loop
    
ProcExit:
    If Not rsAtt Is Nothing Then
        rsAtt.Close
        Set rsAtt = Nothing
    End If
    If Not rsMain Is Nothing Then
        rsMain.Close
        Set rsMain = Nothing
    End If
    Exit Sub
ProcError:
    If Err.Number = 3420 Then
        Resume Next
    ElseIf Err.Number = 3820 Then
        MsgBox "Selected file already exists in this record!"
        Resume Next
    ElseIf Err.Number = 3839 Then
        Resume Next
    Else
        Debug.Print Err.Number, Err.Description, "LoadAttachment"
        Resume ProcExit
    End If
    
End Sub

Private Function ResizeAndReloadAttachment(inPath As String, filename As String)
'ok a fully qualified path is passed in.
'lets resize this puppy and put it into the small folder
'you can clean up TempImages after


Dim img As WIA.ImageFile
Dim IP As ImageProcess
Set IP = CreateObject("WIA.ImageProcess")
IP.Filters.Add IP.FilterInfos("Scale").FilterID
IP.Filters(1).Properties("MaximumWidth") = 448
IP.Filters(1).Properties("MaximumHeight") = 336
            
img.LoadFile inPath
Set img = IP.Apply(img)
img.SaveFile strPath = CurrentProject.Path & "\small\" & filename

End Function

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Nick67
Nick67
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.