Couldn't load image

Monkey Forums/Monkey Programming/Couldn't load image

Ironstorm(Posted 2014) [#1]
Hey folks,

I've tried to load a image via HttpRequest, save it to disk and load this file.
Everything works, except for the LoadImage part ... the saved image seems to be correct.

Import mojo
Import brl

Class MyApp Extends App Implements IOnHttpRequestComplete

	Field get_req:HttpRequest
	Field img:Image
	
	Method OnHttpRequestComplete:Void( req:HttpRequest )
	
		Print "Status="+req.Status()
		Print "ResponseText=" + req.ResponseText()
		
		Local testBuffer:= New DataBuffer(req.BytesReceived())
		testBuffer.PokeString(0, req.ResponseText(), "ascii")
		
		Local file:= FileStream.Open("monkey://internal/test_file.jpg", "w")
		file.WriteAll(testBuffer, 0, req.BytesReceived())
		file.Close
		
	End
	
	Method OnCreate()
	
		get_req = New HttpRequest("GET", "http://blackbird-design.de/wp-content/uploads/2014/01/1556295_676172759113229_1731180211_o.jpg", Self)
		get_req.Send
			
		SetUpdateRate 60
	End
	
	Method OnUpdate()

		If KeyHit( KEY_CLOSE ) Error ""
		
		If get_req.Status() = 200 And img = Null Then
			img = LoadImage("monkey://internal/test_file.jpg", 1, Image.MidHandle)
			If Not img Then Error("Couldn't load image...")
		EndIf
		
		UpdateAsyncEvents
	End

	Method OnRender()
	
		Cls
		
		If img Then DrawImage(img, DeviceWidth() / 2, DeviceHeight() / 2)
		
		DrawText "Http GET bytes received="+get_req.BytesReceived(),0,0

	End	
End

Function Main()

	New MyApp

End



nikoniko(Posted 2014) [#2]
Try to load low resolution image. I had trouble with loading high res jpgs from local disk.

PS Example code is running but nothing download to internal folder.


Danilo(Posted 2014) [#3]
Extended the test:

Android: Can write/copy to internal and external, can not write/copy to data
iOS: Can write/copy to internal, can not write/copy to data and external
GLFW (Mac): Can write/copy to internal + external + data, but can't load .jpg (only .png supported)

Could it be that LoadImage() loads only from /data with Android and iOS?
In this case, there is the problem that we can't write to /data.



Ironstorm(Posted 2014) [#4]
Gnargh ... nope. Solved. As nikoniko mentioned, the image was too big... Shame on me. Thanks guys!

Here the working code:

Import mojo

Import brl

Class MyApp Extends App Implements IOnHttpRequestComplete

	Field get_req:HttpRequest, post_req:HttpRequest
	Field img:Image
	
	Method OnHttpRequestComplete:Void( req:HttpRequest )
	
		Print "Status="+req.Status()
		Print "ResponseText=" + req.ResponseText()
		
		Local testBuffer:= New DataBuffer(req.BytesReceived())
		testBuffer.PokeString(0, req.ResponseText(), "ascii")
		
		Local file:= FileStream.Open("monkey://internal/test_file.jpg", "w")
		file.WriteAll(testBuffer, 0, req.BytesReceived())
		file.Close
		
	End
	
	Method OnCreate()
	
		get_req = New HttpRequest("GET", "http://blackbird-design.de/wp-content/uploads/2012/11/pray_by_blitzmaker-d4ygfop.jpg", Self)
		get_req.Send
			
		SetUpdateRate 60
	End
	
	Method OnUpdate()

		If KeyHit( KEY_CLOSE ) Error ""
		
		If get_req.Status() = 200 And img = Null Then
			img = LoadImage("monkey://internal/test_file.jpg", 1, Image.MidHandle)
			If Not img Then Error("Couldn't load image")
		EndIf
		
		UpdateAsyncEvents
	End

	Method OnRender()
	
		Cls(255, 0, 255)
		
		If img Then DrawImage(img, DeviceWidth() / 2, DeviceHeight() / 2)
		
		DrawText "Http GET bytes received="+get_req.BytesReceived(),0,0

	End	
End

Function Main()

	New MyApp

End



Danilo(Posted 2014) [#5]
Gnargh ... nope. Solved. As nikoniko mentioned, the image was too big... Shame on me. Thanks guys!

But that's only when loading a local file!

Your big image works fine on Android and iOS using LoadImageAsync() and LoadImage("http://"...). GLFW does not support .jpg
Import mojo
Import mojo.asyncloaders

Class MyApp Extends App Implements IOnLoadImageComplete

    Field img:Image

    Method OnLoadImageComplete : Void ( image:Image, path:String, source:IAsyncEventSource )
        img = image
    End
    
    Method OnCreate()    
        LoadImageAsync("http://blackbird-design.de/wp-content/uploads/2014/01/1556295_676172759113229_1731180211_o.jpg",1,Image.MidHandle,Self)
        SetUpdateRate 60
    End

    Method OnUpdate()
        UpdateAsyncEvents()
        If KeyHit( KEY_CLOSE ) Error ""
    End

    Method OnRender()
        Cls()
        If img Then DrawImage(img, DeviceWidth() / 2, DeviceHeight() / 2)
    End    
End

Function Main()
    New MyApp()
End

So the question remains, why does the big image load correctly from web, and not from local file?


Ironstorm(Posted 2014) [#6]
But that's only when loading a local file!

That's my intention. To load a image via http, store it on the local drive and load it into the app. I'm trying to program an online-updater.

LoadAsyncImage and a web url works fine, that's right but you can't save the image.

Edit: Damn, working fine on Desktop, but not on Android...


Danilo(Posted 2014) [#7]
You can write and load RAW pixel data on Android+iOS to /internal, and load
this RAW pixel data into a new image with WritePixels().

You have to define your own raw file format, for example save the width + height at the beginning, followed by raw pixel data.
For saving the raw image data, you need to do it in blocks, if the image is larger as the screen (ReadPixels reads from screen).

You could save the RAW pixel data on the web and transfer it directly to device. Maybe compressed RAW data.
Un-compress it on device and load into image with WritePixels.

Hope you get the idea. ;)


nikoniko(Posted 2014) [#8]
Danilo wrote:
Could it be that LoadImage() loads only from /data with Android and iOS?


GLFW too (tested on windows)

Danilo wrote:
GLFW does not support .jpg


WIndows supports.

Danilo wrote:
So the question remains, why does the big image load correctly from web, and not from local file?


May be it's a bug in stb_image.c


Danilo(Posted 2014) [#9]
Danilo wrote:
GLFW does not support .jpg

nikoniko wrote:
WIndows supports.

According to "Programming Guide > File Formats" only .png is supported on all platforms,
and .png is the only supported file format for GLFW. To me this looks like it is not supported,
even if it works on Windows.


nikoniko(Posted 2014) [#10]
Danilo wrote:
According to "Programming Guide > File Formats" only .png is supported on all platforms,


Never read "Programming guide"

GLFW image loader is based STB library https://github.com/nothings/stb
and "in the theory" supports "image loading/decoding from file/memory: JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC"


nikoniko(Posted 2014) [#11]
Danilo wrote:
Your big image works fine on Android and iOS using LoadImageAsync() and LoadImage("http://"...). GLFW does not support .jpg


Why this code doesn't work in GLFW/Windows with neither jpg or png.


nikoniko(Posted 2014) [#12]
The problem was in jpeg compression

This image
http://blackbird-design.de/wp-content/uploads/2014/01/1556295_676172759113229_1731180211_o.jpg

is compressed as progressive jpeg. It is not supported by monkey (really the stb_image jpeg/png open source library doesn't support progressive jpeg, this lib is used in glfw, ios, winrt, cpp targets.