【问题标题】:Read a PNG image using Haxe使用 Haxe 读取 PNG 图像
【发布时间】:2012-12-26 21:22:12
【问题描述】:

使用Haxe编程语言,有没有跨平台的方式读取PNG图片,并从图片中获取像素数据?

我有一个名为 stuff.png 的文件,我想从图像中获取一个 RGB 值数组(作为整数数组)。

【问题讨论】:

  • 为什么这个问题被否决了?
  • 必须是跨平台的吗?在 Flash 中,可以使用 BitmapData 完成。
  • @Banthar 是的,它必须是跨平台的。
  • hxformat 可以读取 PNG 文件,但是级别很低。
  • @Banthar hxformat png 库是否有可用的文档?

标签: haxe


【解决方案1】:

这是使用 Haxe 格式库读取 PNG 文件的示例。您的编译器 args / build.hxml 中需要 -lib format

function readPixels(file:String):{data:Bytes, width:Int, height:Int} {
    var handle = sys.io.File.read(file, true);
    var d = new format.png.Reader(handle).read();
    var hdr = format.png.Tools.getHeader(d);
    var ret = {
        data:format.png.Tools.extract32(d),
        width:hdr.width,
        height:hdr.height
    };
    handle.close();
    return ret;
}

下面是一个如何从上面获取ARGB像素数据的例子:

public static function main() {
  if (Sys.args().length == 0) {
    trace('usage: PNGReader <filename>');
    Sys.exit(1);
  }
  var filename = Sys.args()[0];
  var pixels = readPixels(filename);
  for (y in 0...pixels.height) {
    for (x in 0...pixels.width) {
      var p = pixels.data.getInt32(4*(x+y*pixels.width));
      // ARGB, each 0-255
      var a:Int = p>>>24;
      var r:Int = (p>>>16)&0xff;
      var g:Int = (p>>>8)&0xff;
      var b:Int = (p)&0xff;
      // Or, AARRGGBB in hex:
      var hex:String = StringTools.hex(p,8);
      trace('${ x },${ y }: ${ a },${ r },${ g },${ b } - ${ StringTools.hex(p,8) }');
    }
  }

【讨论】:

  • 你测试过这段代码了吗?我还在为 Haxe 设置 FlashDevelop,所以我还没有机会测试它。
  • 此代码在 Haxe 3.2.1 中似乎不起作用(format.png.Readerformat.png.Tools 不存在)。
【解决方案2】:

您始终可以使用 BitmapData.getPixels/BitmapData.setPixels 访问像素数据。

如果您使用的是 haXe NME,您可以使用 Assets.getBitmapData() 来加载资产图像文件。

如果你想从网络加载图片,那么你可以使用Loader类,它可以异步加载远程图片,但在flash中请注意跨域问题。

对于更通用的 ByteArray -> BitmapData 转换,使用以下代码:

var ldr = new Loader();
ldr.loadBytes(cast(byteArray)); // bytearray contains raw image data
var dp: DisplayObject = ldr.content; // actually ontent should be of Bitmap class
var bitmapData = new BitmapData(Std.int(dp.width), Std.int(dp.height), true, 0);
bitmapData.draw(dp);

【讨论】:

  • 这里有几个问题: .loadBytes 是异步的,所以立即检查它是不可靠的。此外,您不需要对内容进行 blit,它们已经是位图数据。 var bitmapData = cast(ldr.content, nme.display.BitmapData);为了更简单的解决方案: var bitmapData = nme.display.BitmapData.load("mypng.png");
  • 是的,你是对的,文档说 loadBytes 是异步的,但是这在实践中一直有效,在 nme 本机和闪存中。
  • 嗨,我承认以前的 cmets 中的错误。经过测试,Loader.loadBytes() 在独立的 Flash 播放器中同步工作,但在浏览器插件中异步工作,所以 Matt 是对的,我的代码应该这样修改: var ldr = new Loader(); ldr.loadBytes(cast(byteArray)); ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, function(_) { data = cast(ldr.content, Bitmap).bitmapData; } );
  • 是否有必要在 Haxe 的内存中加载整个文件,然后才能访问它的原始数据?在 Flash 中,这是强制性的,而且……令人生畏。
猜你喜欢
  • 1970-01-01
  • 2012-01-11
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 2014-07-27
  • 1970-01-01
  • 2013-03-02
  • 2015-07-12
相关资源
最近更新 更多