INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Is There Any Way to Retrieve an Embedded Picture on an Access Report?

Is There Any Way to Retrieve an Embedded Picture on an Access Report?

Is There Any Way to Retrieve an Embedded Picture on an Access Report?

(OP)
Hey guys,

We've are in a bit of a pickle here at work. We have an Access report that allows users to reprint 1099 forms. Well, the form changed this year, and I've been tasked with editing the report. The problem is the report itself is actually an embedded image file of the 1099 with table fields placed on top of it. I need to be able to open the file and somehow edit it.


Unfortunately, when I got to report problems, and click the elipse button for the picture, it only takes me to my local machine. We can't find the original image file. It looks like we are totally screwed here, but I am hoping maybe someone can offer a suggestion. How does Access retrieve the image if the physical image file no longer exists anyways? Much appreciated.

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

I do not believe there is a way to retrieve it. Why not just scan this years form and embed that?

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

Can you back up the report, open in design view, remove the table fields, then copy and paste the image into a new blank report?
Or paste into a Word doc and save that?

Beir bua agus beannacht!

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

Of course you can ...

An embedded image has PictureData associated with it, which is in fact just the binary representation of the bitmap. So all we need to do is get that into a convenient format for VBA, such as an OLE Picture. We can do this using code slightly adapted from something I put together for the VB6 about 11 years ago (thread222-708828: Pulling an image from the web); there are other variants created by others around on the internet.

CODE

Option Explicit

Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpsz As Any, pclsid As Any) As Long
Private Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As Long, ppstm As Any) As Long
Private Declare Function OleLoadPicture Lib "olepro32" (pStream As Any, ByVal lSize As Long, ByVal fRunmode As Long, riid As Any, ppvObj As Any) As Long
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal uFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long)
Const GMEM_MOVEABLE = &H2

Private Function PictureFromRawBits(bytes() As Byte) As IPicture
    Dim cbMem As Long, hMem As Long, IPic(15) As Byte, istm As Object
    ' data length
    cbMem = (UBound(bytes)) - LBound(bytes) + 1
    ' allocate global memory block
    hMem = GlobalAlloc(GMEM_MOVEABLE, cbMem)
    ' copy picture data to global memory block
    CopyMemory ByVal GlobalLock(hMem), bytes(LBound(bytes)), cbMem
    ' reset lock count
    GlobalUnlock hMem
    ' create stream object from global memory
    CreateStreamOnHGlobal hMem, 1, istm
    ' fill the Guid of IPicture interface from its CLSID
    CLSIDFromString StrPtr("{7BF80980-BF32-101A-8BBB-00AA00300CAB}"), IPic(0)
    ' create picture from stream object
    OleLoadPicture ByVal ObjPtr(istm), 0, 0, IPic(0), PictureFromRawBits
    ' free global memory
    GlobalFree hMem
End Function

Private Function PictureFromPictureData(myPictureData As Variant) As IPicture
    Dim rawbits() As Byte
    rawbits = myPictureData
    Set PictureFromPictureData = PictureFromRawBits(rawbits())
End Function

Public Sub example()
    Dim RecoveredPicture As StdPicture
    Set RecoveredPicture = PictureFromPictureData(Reports.Item(0).Controls(0).PictureData) ' or wherever your embedded image is
    SavePicture RecoveredPicture, "<yourfilename.bmp>"
End Sub 

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

Here is a slightly easier version. The two functions depend if it is embedded in a control or embedded in a form. It saves the image to the current folder.

CODE

Private Sub Command0_Click()
  'savePictinForm Me.Form
  savePictInControl Me.Image1
End Sub

Public Function savePictInForm(frm As Access.Form)
    Dim fname As String 'The name of the file to save the picture to
    Dim pngImage As String 'Stores the image data as a string
    Dim iFileNum As Double
    
    fname = CurrentProject.Path & "\Temp.png"
   
    iFileNum = FreeFile 'The next free file from the file systemc
    pngImage = StrConv(frm.PictureData, vbUnicode) 'Convert the byte array to a string
    MsgBox "Saved to: " & fname
    'Writes the string to the file
    Open fname For Binary Access Write As iFileNum
        Put #iFileNum, , pngImage
    Close #iFileNum
End Function

Public Function savePictInControl(ctrl As Access.Control)
    Dim fname As String 'The name of the file to save the picture to
    Dim pngImage As String 'Stores the image data as a string
    Dim iFileNum As Double
    
    fname = CurrentProject.Path & "\Temp.png"
   
    iFileNum = FreeFile 'The next free file from the file systemc
    pngImage = StrConv(ctrl.PictureData, vbUnicode) 'Convert the byte array to a string
    MsgBox "Saved to: " & fname
    'Writes the string to the file
    Open fname For Binary Access Write As iFileNum
        Put #iFileNum, , pngImage
    Close #iFileNum
End Function 

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

>Temp.png

Er ... why png?

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

Quote:

Er ... why png?
I guess you could write a lot of code to figure out the real format from the header.
http://www.mikekunz.com/image_file_header.html
But in trutch you can basically pick any common extension and will still open. I put in a JPG image and tried the code with .emf, .bmp, .png and it still opened. However, the easiest way to get the real extension is to just use the original file name. That is in the .picture property

CODE

Public Function savePictInControl(ctrl As Access.Control)
    Dim filename As String 'The name of the file to save the picture to
    Dim strImage As String 'Stores the image data as a string
    Dim iFileNum As Double
    Dim realName As String 'The name of the original embedded file
    
    realName = ctrl.Picture
    filename = CurrentProject.Path & "\" & realName
    iFileNum = FreeFile 'The next free file from the file systemc
    strImage = StrConv(ctrl.PictureData, vbUnicode) 'Convert the byte array to a string
    Debug.Print pngImage
    MsgBox "Saved to: " & filename
    'Writes the string to the file
    Open filename For Binary Access Write As iFileNum
        Put #iFileNum, , strImage
    Close #iFileNum
End Function 

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

The format held in PictureData is always bmp, no matter what the format (or extension) of the original image file.

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

Quote:

The format held in PictureData is always bmp, no matter what the format (or extension) of the original image file
No, that is incorrect. It is held in its native format. If you have something that supports otherwise, please provide.
Just to verify I did the following. I ran the above code using an embedded GIF, JPG, BMP, and PNG. However I did not save with any file extensions.
I then ran the four files without extensions through "Analyze It!". It identified all in their correct formats.

RE: Is There Any Way to Retrieve an Embedded Picture on an Access Report?

Interesting. My comment was based on out-of-date info, and I stand corrected.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close