B4J Question Downloading pictures with non-ui app

Daestrum

Expert
Licensed User
Longtime User
Have a look at javax.imageio that might do what you want.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
something like
B4X:
' address to read from
    Dim address As String = "https://sample-videos.com/img/Sample-jpg-image-50kb.jpg"
    ' set up the variables we need
    Dim j As JavaObject
    Dim pic As JavaObject
    Dim url As JavaObject
    Dim output As JavaObject

   ' make the url
    url.InitializeNewInstance("java.net.URL",Array(address))

    'set up imageio
    j.InitializeStatic("javax.imageio.ImageIO")

    ' read the image
    pic = j.RunMethod("read",Array(url))

    ' set up the output file
    output.InitializeNewInstance("java.io.File",Array("c:/temp/myPicture.jpg"))

    ' write the image
    j.RunMethod("write",Array(pic,"jpg",output))
 
Last edited:
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
as an alternative, you could do the whole thing in b4x, eg:
B4X:
    j.download("https://www.b4x.com/android/forum/data/avatars/m/0/161.jpg")

and then:
B4X:
    If j.Success Then
        Dim inp As InputStream = j.GetInputStream

        Dim out As OutputStream
        out.InitializeToBytesArray(0)
        
        Dim buffer(1024) As Byte
        Dim count As Int = 0
        count = inp.ReadBytes(buffer, 0, buffer.length)
        Log("this read: " & count & " bytes")
        
        Do While count > -1
            out.WriteBytes( buffer, 0, count )
            count = inp.ReadBytes(buffer, 0, buffer.length)
            Log("this read: " & count & " bytes")
        Loop
        
        
        Dim derez() As Byte = out.ToBytesArray

        out.Close

        j.Release
        Log(derez.Length & " raw bytes")
        File.WriteBytes(File.DirApp,"derez.jpg",derez)
    Else
        Log(j.response.ErrorResponse)
    End If
 

Attachments

  • derez.png
    derez.png
    13.4 KB · Views: 52
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
or as a sub
called like
B4X:
getAndSaveImage("https://sample-videos.com/img/Sample-jpg-image-50kb.jpg","c:/temp/myPicture","")

'or if you want to read a jpg and then save as a png

getAndSaveImage("https://sample-videos.com/img/Sample-jpg-image-50kb.jpg","c:/temp/myPicture","png")

B4X:
Sub getAndSaveImage(address As String, outPutFilePathAndNameNoExtention As String, override As String)
   
    Dim picType As String = address.SubString(address.LastIndexOf(".")+1)
   
    If override <> "" Then picType = override
   
    Dim j, pic, url, output As JavaObject

    url.InitializeNewInstance("java.net.URL",Array(address))
   
    j.InitializeStatic("javax.imageio.ImageIO")
   
    pic = j.RunMethod("read",Array(url))
   
    output.InitializeNewInstance("java.io.File",Array(outPutFilePathAndNameNoExtention & "." & picType))
   
    j.RunMethod("write",Array(pic, picType, output))
   
    Log("wrote (" & address & ") image to " & outPutFilePathAndNameNoExtention & "." & picType)
End Sub

I have another sub that will display the image to you in a non-ui app if you want it.
 
Last edited:
Upvote 0

aeric

Expert
Licensed User
Longtime User
Upvote 0

derez

Expert
Licensed User
Longtime User
Thanks for all the replies, I'll used Daestrum's sub and it works very nicely.
 
Last edited:
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
The display sub incase anyone was curious ( called after the pic = j.RunMethod() line as showImage(pic) )
B4X:
Sub showImage(img As JavaObject)
    Dim h, w As Int
    h = img.RunMethod("getHeight",Null)
    w = img.RunMethod("getWidth",Null)
    Dim frame, label, imageicon As JavaObject
    frame.InitializeNewInstance("javax.swing.JFrame",Null)
    frame.RunMethod("setSize",Array(w,h+50)) ' allow for title bar
    label.InitializeNewInstance("javax.swing.JLabel",Null)
    imageicon.InitializeNewInstance("javax.swing.ImageIcon",Array(img))
    label.RunMethod("setIcon",Array(imageicon))
    frame.RunMethod("setTitle",Array("The picture"))
    frame.RunMethod("add",Array(label))
    frame.RunMethod("setAlwaysOnTop",Array(True))
    frame.RunMethod("setVisible",Array(True))
    frame.RunMethod("setDefaultCloseOperation",Array(frame.GetFieldJO("DISPOSE_ON_CLOSE")))
End Sub
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
I don't understand why it needs to be so complicated.
How I do is:
B4X:
Sub DownloadImage
    Dim job As HttpJob
    job.Initialize("", Me)
    job.Download("https://picsum.photos/200/300")
    Wait For (job) JobDone(job As HttpJob)
    If job.Success Then
        Dim inp As InputStream = job.GetInputStream
        Dim out As OutputStream = File.OpenOutput(File.DirApp, "image.jpg", False)
        File.Copy2(inp, out)
        out.Close
        Log("Image saved.")
    End If
    job.Release
End Sub
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
Open image:

B4X:
Sub OpenImage (Path As String)
    Dim shl As Shell
    ' Windows
    'shl.Initialize("shl", "cmd", Array As String("/c", "start", Path))
    ' Linux
    shl.Initialize("shl", "eog", Array As String(Path))
    shl.Run(-1)
    Wait For shl_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
    If Success And ExitCode = 0 Then
        Log("Success")
        Log(StdOut)
    Else
        Log("Error: " & StdErr)
    End If
End Sub
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
@aeric Unfortunately your OpenImage does nothing on my machine and does not show the image
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I am on windows - and uncommented the lines for windows.

As an example to show a command window (that stays open so I can use it) - my command has to be
shl.Initialize("shl", "cmd.exe", Array As String("/c","start","cmd.exe"))
 
Upvote 0

teddybear

Well-Known Member
Licensed User
@aeric Unfortunately your OpenImage does nothing on my machine and does not show the image
Open image:

B4X:
Sub OpenImage (Path As String)
    Dim shl As Shell
    ' Windows
    'shl.Initialize("shl", "cmd", Array As String("/c", "start", Path))
    ' Linux
    shl.Initialize("shl", "eog", Array As String(Path))
    shl.Run(-1)
    Wait For shl_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
    If Success And ExitCode = 0 Then
        Log("Success")
        Log(StdOut)
    Else
        Log("Error: " & StdErr)
    End If
End Sub
The eog is imageview app on linux, if you are using windows , replace eog with "mspaint" or other imgview app,it also works
 
Upvote 0

derez

Expert
Licensed User
Longtime User
The getandsave sub from Daestrum works well in linux mint Virginia (20.1), sorry I have not checked the other solutions.
 
Upvote 0
Top