[RESOLVED] Saving a png to desktop

I used to be able to save png files I generated in openfl, and with the snippet attached you still can when you use -Dlegacy

I tried to update the code to the ‘new’ openfl, but I run into something strange (perhaps an bug?)

Try to test the code without -Dlegacy

lime test neko
I get this error:
Main.hx:50: Error writing file /path/to/your/Desktop/test.png: Invalid field access : length

Which basically is: bytearray doesn’t have length
http://docs.openfl.org/lime/utils/ByteArray.html#length
(documentation agrees!!)
but what would work???

import openfl.display.Sprite;
import openfl.Assets;
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.PNGEncoderOptions;
import openfl.utils.ByteArray;
import openfl.geom.Rectangle;
import haxe.io.Output;
import sys.io.FileOutput;

class Main extends Sprite {
		
	public function new () 
	{	
		super ();	
		var _bit = new openfl.display.Bitmap(Assets.getBitmapData( 'assets/robot.jpg'));
		this.addChild(_bit);
		saveImage(_bit.bitmapData,"/path/to/your/Desktop/test.png");
	}

	public function saveImage(image:BitmapData, outputFile:String):Void
	{
		#if (cpp || neko)

			var path;
			// path = Sys.getCwd();
			// path = path.substr(0, path.indexOf('Export')) + "test2.png"; 

			path = outputFile;

			#if openfl_legacy
				var imageData:ByteArray = image.encode('png', 1);
			#else
				var imageData:ByteArray = image.encode(new Rectangle(), PNGEncoderOptions);
			#end
			
			var fo:FileOutput = sys.io.File.write(path, true);
			try {

				fo.writeBytes(imageData, 0, imageData.length );
				
				#if openfl_legacy
					// fo.writeBytes(imageData, 0, imageData.length );
				#else
					// fo.writeBytes(imageData, 0, imageData.length );
				#end

				trace( "save path done: " + path );
			} catch (e:Dynamic){
				trace("Error writing file " + path + ": " + e);
			}
			fo.close();
		#end
	}	
}

Have you tried the static simple function File.saveBytes?
http://api.haxe.org/sys/io/File.html

There is also FileOutput.write.
http://api.haxe.org/haxe/io/Output.html

They don’t require to input a length, and given your use, they are enough.

Granted, though, you code should work…
Still, check that imageData isn’t null.

thx for your reply:

I have tried

File.saveBytes (path, imageData);

and it returns the same Error:
Error writing file /path/to/your/Desktop/test.png: Invalid field access : length

What are your versions of Lime and OpenFl installed?

Also, from your code, try using ByteArray.getLength()?
http://docs.openfl.org/lime/utils/ByteArray.html#getLength

Also try imageData.position=0, and then use imageData.bytesAvaillable for length.

I have tried that also:

var fo:FileOutput = sys.io.File.write(path, true);
fo.writeBytes(imageData, 0, imageData.getLength() );
fo.close();

Gives me error:

Invalid field access : getLength

fo.writeBytes(imageData, 0, imageData.bytesAvailable );

Gives me error:

Invalid field access : length

Perhaps it a bug, time to file a bugreport?

Yeah, it has to be a bug.
But it would have been fine to find a workaround.
Sorry I couldn’t help you more.
Regards.

I think your problem is this line:

var imageData:ByteArray = image.encode(new Rectangle(), PNGEncoderOptions);

Try:

var imageData = image.encode (image.rect, new PNGEncoderOptions ());

:slight_smile:

1 Like

yes that is the answer!

I have been breaking my head over it, so thx!