Android Question Download image from php website

Mark Read

Well-Known Member
Licensed User
If I paste this code (from a gallery website) into my web browser:

B4X:
www.somewebpage.com/bod.php?slideID=64C94333ECB3F3122B

A dialog box is generated with the message "you have chosen to open imagex.jpg....open or save" (a typical download window).

I am trying just to get the image into my app using HttpUtils2 and download:

B4X:
ImageJob.Download(images.Get(ImageIndex))

Images is a list containing all the links, which is working fine. All links are correct. The JobDone is not called and I have no error message. My app continues, menus work etc but there are no images.

Can anyone help.

Regards
Mark
 

Mark Read

Well-Known Member
Licensed User
Thanks, I had a look at this but the images are not called using php. Getting images via html is no problem.
I think my code would work if the image would be directly loaded into the browser but it is not, it jumps straight to a download which I cannot stop.
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Okay, I think I understand the problem. Its in the bod.php file. Any idea what I can do to solve this. If I can find no solution, I cannot complete my App.
Regards
Mark
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Is there a possibility to inject a javascript into the webview to save the image? Just a thought, as the image is already in the app. Warwound seems to be a javascript expert.
 
Upvote 0

DonManfred

Expert
Licensed User
The custom typ application/force-download will override any javascript. It will FORCE a download.
You can inject javascript with webview, yes. But i think that javascript can not get the image. and therefore it cannot send the image to your app with the javascriptinterface.

But maybe the webview-guru, Martin, has an solution. I do not have one sorry
 
Upvote 0

warwound

Expert
Licensed User
I guess you have no control over the website PHP?

Assuming that you can't change the PHP i can think of only one option - to use a server side script as a proxy script to get the image from domai.com and return it to your b4a application.
Ie your b4a application sends the requested image url to a script on a server, the script gets the image (working around the application/force-download MIME type) and returns it to your application.

Another assumption there is that a script such as a PHP script could get the image from domai.com and that the application/force-download MIME type wouldn't be a problem.

PHP:
<?php
if (isset($_GET['slideUUID'])) {
   $url = 'http://www.domai.com/bod.php?slideUUID='.$_GET['slideUUID'];
   $raw_data = file_get_contents($url);
   $image = imagecreatefromstring($raw_data);
   header("Content-type: image/jpeg");
   imagejpeg($image);
} else {
   echo 'No slideUUID requested';
}
?>

http://b4a.martinpearman.co.uk/temp/bypass-mime.php?slideUUID=453DAD761515BF64C94333ECB3F3122B

Right now that link when opened in my browser says the image cannot be displayed as it contains errors.
A few minutes ago my browser was displaying about the first two thirds of the image - the last third missing.

Maybe domai.com have noticed my repeated requests to the same image url and temporarily blocked my server's ip address?
Maybe the problem is elsewhere.

But this is i think your only solution - if you can get it working and hosted online and not be blocked by domai.com if it detects you downloading the images.

Martin.
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Martin: Thx for your reply. You are correct, I have no control over the website php. I also tried your link and get nothing apart from an error message.

I may have stumbled upon another workaround though. If I build a new html page with just this link and nothing else ...

B4X:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>MR.Test</title>
<base target="bottom">

</head>

<body text="#FFFFFF" vlink="#800080" style="font-family: Tahoma; font-size: 12pt" bgcolor="#000000">
<center>


<img border="0" src="http://www.domai.com/bod.php?slideUUID=453DAD761515BF64C94333ECB3F3122B">

</center>

</body>

</html>

and open this file locally on my pc with firefox, then the image is there. If I was to generate a html page in my app and load it into a webview, I seem to recall that I could save the webview as an image. It would not be perfect but it might work. What do you think?

Regards
Mark
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
YES! It worked. This simple code did the trick.

B4X:
webview1.Initialize("")
Activity.AddView(webview1, 0,0,100%x,100%y)
webview1.LoadHtml( "<html><body><img src='http://www.domai.com/bod.php?slideUUID=453DAD761515BF64C94333ECB3F3122B'></body></html>")

I will make small adjustments to get the fill size. Now somewhere I read about a method to capture the webview as a screenshot. Time to go searching....

Many thanks to Martin and Danke DonManfred für deine Hilfe.
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
[Solved] Managed to get a jpg file using this code. Its not yet perfect but its a good start.

B4X:
Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim WebView1 As WebView
   'Dim WebViewExtras1 As WebViewExtras
   Dim MyImage As Bitmap
   Dim Timer1 As Timer
End Sub

Sub Activity_Create(FirstTime As Boolean)
   'Do not forget to load the layout file created with the visual designer. For example:
   'Activity.LoadLayout("Layout1")
   WebView1.Initialize("")
   Timer1.Initialize("Timer1",2000)
   Activity.AddView(WebView1, 0,0,100%x,100%y)
   'WebViewExtras1.addJavascriptInterface(WebView1, "B4A")
  'WebViewExtras1.addWebChromeClient(WebView1,"")
   WebView1.LoadHtml( "<html><body><img src='http://www.domai.com/bod.php?slideUUID=453DAD761515BF64C94333ECB3F3122B'></body></html>")
   Timer1.Enabled=True
End Sub

Sub Timer1_Tick
   Log("Timer1_Tick triggered")
   MyImage=WebView1.CaptureBitmap
   
   Dim out As OutputStream
  out = File.OpenOutput(File.DirRootExternal, "webview.jpg", False)
  MyImage.WriteToStream( out, 100, "JPEG")
  out.Close
   Timer1.Enabled=False
   Activity.Finish
End Sub

Sub WebView1_PageFinished (Url As String)
   Log("PageFinished triggered")
   MyImage=WebView1.CaptureBitmap
   
   Dim out As OutputStream
  out = File.OpenOutput(File.DirRootExternal, "webview.jpg", False)
  MyImage.WriteToStream( out, 100, "JPEG")
  out.Close
   
   Activity.Finish
End Sub

Had to use a timer to trigger the capture as injecting javascript and using PageFinished did not work. Maybe because its not an URL?? No idea.

Maybe this solution will help others.
Regards
Mark
 
Upvote 0

warwound

Expert
Licensed User
What do you think?

The WebView and browser send various header info when they request the image and the PHP script must look at the headers that accompany a request.
If the PHP script thinks the request is from a browser it returns the image 'normally', otherwise it adds the application/force-download MIME type and forces the image to be saved.
Now could you request the image using HTTPUtils and set a header that'll trick the PHP script into returning the image 'normally'?
Maybe the PHP script just looks for the browser id in the header info and that should be quickly 'spoofed'.

The WebView PageFinished event generally means that the page content has all been retrieved from it's origin and loaded BUT it doesn't mean that the content has actually been rendered.
I'm not sure what easy ways there are to detect when the WebView has completely rendered the loaded content.

If you could get that spoofed header to work you could do away with the WebView.

Martin.
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
I am still working on modifying my app to get this working. Timing seems to be a theme.
Interesting for me is if I try to load the image as in post #5, I can only download but if I set an image src as in post #13 then it seems to work. I don't understand what the difference is with regard to your comment:
The WebView and browser send various header info when they request the image and the PHP script must look at the headers that accompany a request.

I will continue with my app at present but if it does not work, I will get back to you about your method.

Many thanks
Mark
 
Upvote 0

warwound

Expert
Licensed User
When a WebView or browser requests the image, the request contains additional info such as the UserAgent.
Take a look here: http://whatsmyuseragent.com/.

If you request the image using HttpUtils then no UserAgent is sent or the UserAgent is different from the UserAgent sent by the WebView or browser.

And i'd guess that the bod.php examines the UserAgent that accompanies a request and decides whether to return the image with a standard image/jpeg MIME type or whether to return the image with a application/force-download MIME type.

My suggestion is that if you can set the UserAgent when using HttpUtils2 to be the same as the UserAgent used by the WebView or browser then you might find that bod.php returns the image with the image/jpeg MIME type instead of forcing a download.

There's a code example in this post that shows how to set headers.

Martin.
 
Upvote 0
Top