Loading image from memory

Hello, everyone. I’ve been testing the BytesArray method of loading images into a Bitmap image but I cannot seem to get it to appear on the game screen. I have a folder with my art and within it has art/world/terrain.png. I have compressed it into an ordinary zip, then changed the file extension to .dat.

To read the zip contents and load a specific resource, I use the following code:

package data;
import haxe.io.Bytes;
import openfl.display.BitmapData;
import sys.io.File;
import haxe.zip.Reader in ZipReader;

using StringTools;

class Reader
{

    public static function readResource(file:String, res:String = "art"):Bytes
    {
        var result:Bytes = null;
        var res_path:String = "";
        
        switch (res)
        {
            case "art":
                res_path = "data/art.dat";
            case "dialogue":
                res_path = "data/dialogue.dat";
        }
        
        var _in_file = File.read(res_path);
        if (_in_file == null)
        {
            trace('The file $res_path could not be read.');
            return null;
        }
        
        var _entries = ZipReader.readZip(_in_file);
        
        _in_file.close();
        
        for (entry in _entries)
        {
            if (entry.fileName == file)
            {
                result = entry.data;
                break;
            }
        }
        
        return result;
    }
    
}

I will probably optimise this code later, but for now I’m just testing.

I use the following entry point class to test out this image:

class Main extends Sprite 
{
    
	public function new() 
	{
		super();
		
        var data = Reader.readResource("art/world/terrain.png");
        
        if (data == null)
        {
            trace("Could not find resource");
            return;
        }
        
        var bytes = ByteArray.fromBytes(data);
        
        var bmp = new Bitmap(BitmapData.fromBytes(bytes));
        
        addChild(bmp);
	}
    
}

But all I get is a blank screen, without the image:

Any clues as to why this might be happening?

The bytes of a .png image isnt the right format for bitmapped data. The png is compressed, so you need to decode that. You could either use the haxe format lib, which i believe would be synchronous (though i havent actually used this method), or just use Loader to load and decode it for you, eg from haxeui2:

    private function getImageFromHaxeResource(resourceId:String, callback:String->ImageInfo->Void) {
        var bytes = Resource.getBytes(resourceId);
        var ba:ByteArray = ByteConverter.fromHaxeBytes(bytes);
        var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e) {
            if (loader.content != null) {
                var bmpData = cast(loader.content, Bitmap).bitmapData;
                var imageInfo:ImageInfo = {
                    data: bmpData,
                    width: bmpData.width,
                    height: bmpData.height
                }
                callback(resourceId, imageInfo);
            }
        });
        loader.loadBytes(ba);

    }

Which target? I believe the straight “fromBytes” should work on non-Flash targets, assuming the bytes are good

Really? Thats interesting. So it automatically detects if its a png, jpeg etc (presumably by the first few bytes) and decodes it in place synchronously?

I’m using the neko target, primarily, to test things on.

I did start digging around into the source code of openfl and lime, to see if there was a problem somewhere in there. I think I managed to get a trace up to line 1160 of lime.graphics.Image, but that’s as far as it went.

So the data variable is null and is the reason why I’m not seeing anything.

If you try writing the bytes to a file, do you get a working png? (ie. are the bytes correct)