Scaling Imaging from URL using Web Broswer Control - vba

I am having a problem trying to get a Web Browser control in a MS Access form to display an image from a URL correctly.
I am using .navigate (strImagePath) to place the imaging in to WebBrowser1. That works fine. The images are jpg and I have the full path and image filename.
The problem is the that the image is displayed at 100% scale, which is larger than the size of the browser. I can use zoom (OLECMDID_OPTICAL_ZOOM) to scale the image, but this only works if I know the size of the image, which I don't to get the right zoom factor.
Ideally, I would like to have the image fit to window without having to determine the image size.
It that is not possible, the other option is to determine the image size and then set the appropriate zoom. I have not figured a way to determine the image size without saving it locally. Which would be a big overhead and add a unacceptable lag to the form display, specially when move through records. Any ideals here?
Thanks

I was able to get it running after the code from Thomas.
There is the final code.
Public Function DisplayImage(ctlImageControl As Control, strImagePath As Variant) As String
On Error GoTo Err_DisplayImage
Dim strResult As String
Dim intHeight As Integer
Dim intWidth As Integer
Dim intHeightZoom As Integer
Dim intWidthZoom As Integer
Dim intPageZoom As Integer
With ctlImageControl
If strImagePath = "" Then
.Visible = False
strResult = "No image name specified."
Else
.Visible = True
.Navigate (strImagePath)
Do While .Object.Busy Or .Object.ReadyState <> 4 'wait to imaged loaded
DoEvents
Loop
intHeight = .Document.images(0).clientHeight
intWidth = .Document.images(0).clientWidth
intHeightZoom = CLng(21600) / intHeight
intWidthZoom = CLng(43200) / intWidth
If intHeightZoom < intWidthZoom Then
intPageZoom = intHeightZoom
Else
intPageZoom = intWidthZoom
End If
.Object.ExecWB OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, _
CLng(intPageZoom), vbNull
strResult = "success"
End If
End With
Exit_DisplayImage:
DisplayImage = strResult
Exit Function
Err_DisplayImage:
Select Case Err.Number
Case 2220 ' Can't find the picture.
ctlImageControl.Visible = False
strResult = "Can't find image in the specified name."
Resume Exit_DisplayImage:
Case Else ' Some other error.
MsgBox Err.Number & " " & Err.Description
strResult = "An error occurred displaying image."
Resume Exit_DisplayImage:
End Select
End Function
There the function is called by
Me!txtFaceResults = DisplayImage(Me!WebBrowser1, strFullImageName)
While it works to zoom the images to a uniform size, the scaling is still off. But the general process works of loading the images in to the ActiveX Web Browser object. Reads the image size and calculates a zoom factor and then apply the zoom. It is important to wait for the image to load, otherwise you will either get an error or the size of the previously loaded image.
I was not able to use HtmlImg Type as Thomas used, so I got the elements individually. I used the documentation on Mozilla at:
https://developer.mozilla.org/en-US/docs/Web/API/Element
to see the element available.

If you have only the image loaded, the following code will get you the width and height of that image.
Dim img As HtmlImg
Set img = Me.WebBrowser1.Document.images(0)
Debug.Print img.naturalHeight, img.naturalWidth
However, I was not really able to calculate the correct zoom factor nor to pass a variable zoom factor to the ExecWB-method - I always got a runtime error, not matter which data type I used (constant values are working).
Plus, at least in my tests, the image was displayed with (white) borders which also would influence the zoom factor. Anyhow, the width and height are exactly the dimensions of the test image I was playing with.

Related

How can I save an image using System.Drawing.Imaging without auto rotating it?

When I resize my image and save it using the "System.Drawing.Imaging" save function, it adds the rotation embedded from the EXIF data and rotates my good original picture 180 degrees. I tried saving it in a different format to remove the EXIF data but it still includes the EXIF rotation for the new picture. Any ideas on how I can save the picture in the orientation I can see in the thumbnails .
Private Sub ClearEXIF()
Dim Pname As String = Nothing
For Each Fil In Directory.GetFiles(DlDir)
OK2Go = False
If Fil.Contains("jpg") Then OK2Go = True
If Fil.Contains("jpeg") Then OK2Go = True
If OK2Go Then
Dim bmp As Bitmap = Image.FromFile(Fil)
Pname = GetLastName(Fil) 'this function gets the name of the jpg without the path info
temp1 = Split(Pname, ".")
bmp.Save("C:\Temp\Flat\" & temp1(0) & "+" & temp1(1) & ".png", ImageFormat.png)
bmp.Dispose()
End If
Next
MsgBox("Done")
End Sub

MS Access VBA Dynamically Show Pics From URL

I found this code from here:
Show Pictures Directly From URLs in Access Forms and Reports
I have this code on my form:
Public Function PeopleImage()
'FUNCTION TO SET THE IMGPEOPLEPIC WITH THE CURRENT PERSON'S PHOTO, IF THE PHOTO CAN BE FOUND. OTHERWISE A STOCK IMAGE SAYING NO PIC FOUND WILL SHOW
Dim PeoplePic As String
Dim NoPeoplePic As String
Dim ImgDwnld As String
PeoplePic = "https://TheWebAddress.com/People%20Photos/" & Nz(Me.PersonID, 0) & ".jpg"
ImgDwnld = "\\AppServer\AppDir\Storage\Images\" & Nz(Me.PersonID, 0) & ".jpg"
DownloadFile PeoplePic, ImgDwnld, False
NoPeoplePic = "\\AppServer\AppDir\Storage\NoPeoplePic.jpg"
If FileExists(ImgDwnld) Then
Me.ImgPeoplePic.Picture = ImgDwnld
Else
Me.ImgPeoplePic.Picture = NoPeoplePic
End If
Me.ImgPeoplePic.Requery
End Function
When I added the image control ImgPeoplePic I set it to the NoPeoplePic, so that a picture would be set. Now, when I load the form and navigate, it looks like the photo is reloading (it blinks), but it just keeps showing the stock NoPeoplePic.
Anyone know what I'm missing? I feel like I'm so close. I just don't understand what it's not putting in the image that it downloads. I verified that the image downloads to the directory, and that it is there. I debug the path and image and it pulls up with no problem.
Any help is appreciated!

Excel VBA - Crop PDF page using VBA

I wrote a piece of code that crops a pdf page and then re-insert this page in the global pdf using the Adobe Acrobat 10.0 Type Library for Excel VBA.
The code works fine on my computer but crops too much on the one of my co-worker. I think it might come from the resolution (1440x900 for mine, 1600x900 for my co-worker) but I just don't see where the resolution might interfer in the code.
Dim acroRect, jso, page As Object
Dim pdf1 As Acrobat.CAcroPDDoc
Dim nameFile, s, exportCroppedPDF As String
Set acroRect = CreateObject("AcroExch.Rect")
Set pdf1 = CreateObject("AcroExch.PDDoc")
nameFile = "namefile.pdf"
If pdf1.Open(nameFile) Then
Set jso = pdf1.GetJSObject
Set page = pdf1.AcquirePage(pdf1.GetNumPages() - 1)
'These values were found from some tests I did, there is no logic behind them
acroRect.bottom = 22
acroRect.Left = 35
acroRect.Right = 785
acroRect.Top = 589
page.CropPage (acroRect)
exportCroppedPDF = "pathAndNamefile.pdf"
s = jso.extractPages(0, pdf1.GetNumPages() - 1, exportCroppedPDF)
Else
Debug.Print ("Can't open the file!")
End If
pdf1.Close
Set pdf1 = Nothing
Set acroRect = Nothing
Set jso = Nothing
Set page = Nothing
Debug.Print ("Crop successful")
I am not cumfortable at all with this library (the code comes from pieces of code I found on the Internet) so I might have wrote some wrong lines (but it initialy works).
Thanks a lot for your help!
According to the documentation CropPages has 4 arguments where acroRect should be the last one.
returnValue = Object.CropPages( nStartPage, nEndPage, nEvenOrOddPagesOnly, acroRect )
Parameters:
nStartPage: First page that is cropped. The first page in a PDDoc object is
page 0.
nEndPage: Last page that is cropped.
nEvenOrOddPagesOnly Value indicating which pages in the range are cropped. Must be
one of the following:
0 means crop all pages in the range
1 means crop only odd pages in the range
2 means crop only even pages in the range
acroRect An AcroExch.Rect specifying the cropping rectangle, which is
specified in user space.

Slow speed of VBA command (Application.FollowHyperlink) in a local network

I am using a MS Access application in local network, this application have form for display data, and one of the features in the form is opening picture files regarding the data in the form. My issue is opening the pictures are very slow for the Front End users (1 to 5 seconds). This is my function for the opening photos:
Public Sub OpenPicture(PictureName As Variant)
If PictureName <> "" Then
DoCmd.SetWarnings False
Dim iPath , filePath As String
iPath = "C:\photo\"
filePath = iPath & PictureName
Application.FollowHyperlink filePath
DoCmd.Requery
DoCmd.SetWarnings True
End If
End Sub
In the above code, PictureName is the name of the image in the DataForm. I should mention there are Image controls for showing pictures in the DataForm, but these controls are small. My purpose is to crop or rotate these pictures in case of need in other programs.
Also I have a lot of image files (more than 200000) in the image source folder.
Please help me for improving the speed of this function.
Thanks in advance.

Capture Active Window with Keyboard SendKeys

After experiencing problems with Visual Basic's printform quality, I have decided to take a different approach. I am going to simulate an ALT-PRINTSCREEN keyboard key-press to capture the form in its current state.
However, before this happens, I need to remove certain elements from the form (such as the border), and after getting the image, I need to replace these elements. I am having some timing/synchronization problems with this, as I am noticing that certain elements are still on the image that has been copied to the clipboard.
I figured this was due to the fact that it takes time to process the changes, and time for Windows to process the simulated "send keys", so I set up sleep timers. I am having mixed results. I notice that if I don't replace the elements afterwords, the clipboard image appears correctly. However, if I do replace them, even if I set up a 20 second sleep timer, they do not appear.
Therefore, I know there is some sort of synchronization problem, but I am not sure how to fix it. Here is the code I am using:
'Make these forms invisble so they are not printed
Logo.Visible = False
MenuStrip1.Visible = False
ReportsButton.Visible = False
pnlmain.BorderStyle = 0 'remove the border
'Sleep
System.Threading.Thread.Sleep(1000)
'simulate an ALT and PRINTSCREEN key click to get ONLY the report
SendKeys.Send("%{PRTSC}")
'Sleep
System.Threading.Thread.Sleep(1000)
'Now, get the image from the clipboard
Dim formImage As System.Drawing.Image
formImage = My.Computer.Clipboard.GetImage()
Logo.Visible = True
MenuStrip1.Visible = True
ReportsButton.Visible = True
pnlmain.BorderStyle = 1
Changing the sleep durations does not seem to change much (unless they are very low).
Any suggestions?
EDIT: here is the code for draw to bitmap (after modifying the code above):
formImage = New Bitmap(Me.Width, Me.Height, Me.CreateGraphics())
Me.DrawToBitmap(formImage, New Rectangle(0, 0, Me.Width, Me.Height))
When it is sent to the print action:
Dim g As Graphics = e.Graphics
'transform the form image so it fits the height and width of the paper, with a 5 px margin
Dim res = printSettings.PrinterResolutions
Dim newSizeDestinationPoints As Point() = {
New Point(5, 5),
New Point(841, 5),
New Point(5, 956)
} 'These values are based on A4 sized paper
'g.DrawImage(formImage, 5, 5)
g.DrawImage(formImage, newSizeDestinationPoints)
The low quality is not coming from the stretch.