热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何使用javascript从PNG中提取像素信息(getImageDataalternative)

如何解决《如何使用javascript从PNG中提取像素信息(getImageDataalternative)》经验,为你挑选了1个好方法。

我试图从PNG图像中获取像素数据进行处理.目前的方法是使用canvas.drawImagefollow canvas.getImageData(这里的例子).我正在寻找替代品.

当前方法的问题在于浏览器修改受alpha影响的像素值,如此处和此处所讨论的.

之前已经提出过这个问题,但没有令人满意的答案.



1> 小智..:

在不使用canvas的情况下执行此操作的唯一方法getImageData()是将PNG文件作为二进制类型数组加载,并在代码中"手动"解析文件.

先决条件:

为此,您需要PNG规范,您可以在此处找到.

您需要知道如何使用类型化数组(对于此a DataView是最合适的视图).

PNG文件是基于的,您需要知道如何解析块

典型的基于块的文件具有称为FourCC标识符的四字节头,后跟size和misc.数据取决于文件格式定义.

然后在此之后放置,通常包含FOURCC(或四个字符代码),然后是没有块头的块的大小.原则上:

    MAGIC FOURCC
    SIZE/MISC    - depending on definition
    ...

    CHK1         - Chunk FourCC
    SIZE         - unsigned long
    .... data

    CHK2
    SIZE
    .... data

这种格式原则最初来自Commodore Amiga平台和80年代中期的EA/IFF(交错文件格式).

但是在现代,一些供应商已经扩展或改变了块格式,因此对于PNG块,它实际上看起来像这样:

标头(总是8个字节和相同的字节值):

‰PNG       (first byte is 0x89, see specs for reason)
CR + LF    0x0C0A
EOC + LF   0x1A0A

大块:

SIZE      (4 bytes, may be 0 (f.ex. IEND). Excl. chunk header and crc)
FOURCC    (4 bytes, ie. "IHDR", "IDAT")
[...data] (length: SIZE x bytes)
CRC32     (4 bytes representing the CRC-32 checksum of the data)

(有关详细信息,请参阅上面引用的规范链接).

而且PNG的字节顺序(字节顺序)总是大端("网络"顺序).

这使得解析仅支持一些(或所有)块的文件变得容易.对于PNG,您至少需要支持(来源):

IHDR必须是第一块; 它包含(按此顺序)图像的宽度,高度,位深度和颜色类型.

IDAT包含图像,可以在多个IDAT块之间分割.这种拆分会略微增加文件大小,但可以更容易地流式传输PNG.IDAT块包含实际图像数据,它是压缩算法的输出流.

IEND 标记文件结束.

如果您打算支持调色板(颜色索引)文件,您还需要支持PLTE块.解析IHDR块时,您将能够看到使用的是哪种颜色格式(RGB数据类型为2,RGBA类型为6,依此类推).

解析本身很容易,因此您最大的挑战是支持ICC配置文件(当存在于iCCP块中时)来调整图像颜色数据.典型的块是gamma chunk(gAMA),它包含一个可用于将数据转换为线性格式的伽玛值,以便在应用显示伽玛时正确显示(还有其他与颜色相关的特殊块).

第二大挑战是使用INFLATE 的减压.您可以使用PAKO zlib端口等项目为您完成此任务,并且此端口的性能接近本机zlib.除此之外,如果要对数据进行错误检查(推荐),还应支持CRC-32检查.

出于安全原因,您应始终检查字段是否包含它们所假设的数据,以及使用0或定义的数据初始化保留的空间.

希望这可以帮助!

示例块解析器:(注意:不会在IE中运行).

function pngParser(buffer) {

  var view = new DataView(buffer),
      len = buffer.byteLength,
      magic1, magic2,
      chunks = [],
      size, fourCC, crc, offset,
      pos = 0;  // current offset in buffer ("file")

  // check header
  magic1 = view.getUint32(pos); pos += 4;
  magic2 = view.getUint32(pos); pos += 4;

  if (magic1 === 0x89504E47 && magic2 === 0x0D0A1A0A) {

    // parse chunks
    while (pos >> 24) + c(int >>> 16 & 0xff) + c(int >>> 8 & 0xff) + c(int & 0xff);
  }
}

// USAGE: ------------------------------------------------

fetch("//i.imgur.com/GP6Q3v8.png")
  .then(function(resp) {return resp.arrayBuffer()}).then(function(buffer) {

  var info = pngParser(buffer);

  // parse each chunk here...
  for (var i = 0, chunks = info.chunks, chunk; chunk = chunks[i++];) {
    out("CHUNK : " + chunk.fourCC);
    out("SIZE  : " + chunk.size + " bytes");
    out("OFFSET: " + chunk.offset + " bytes");
    out("CRC   : 0x" + (chunk.crc>>>0).toString(16).toUpperCase());
    out("-------------------------------");
  }

  function out(txt) {document.getElementById("out").innerHTML += txt + "
"} });
body {font: 14px monospace}

推荐阅读
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 深入解析Java虚拟机的内存分区与管理机制
    Java虚拟机的内存分区与管理机制复杂且精细。其中,某些内存区域在虚拟机启动时即创建并持续存在,而另一些则随用户线程的生命周期动态创建和销毁。例如,每个线程都拥有一个独立的程序计数器,确保线程切换后能够准确恢复到之前的执行位置。这种设计不仅提高了多线程环境下的执行效率,还增强了系统的稳定性和可靠性。 ... [详细]
  • 【妙】bug称它为数组越界的妙用
    1、聊一聊首先跟大家推荐一首非常温柔的歌曲,跑步的常听。本文主要把自己对C语言中柔性数组、零数组等等的理解分享给大家,并聊聊如何构建一种统一化的学习思想 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 重要知识点有:函数参数默许值、盈余参数、扩大运算符、new.target属性、块级函数、箭头函数以及尾挪用优化《深切明白ES6》笔记目次函数的默许参数在ES5中,我们给函数传参数, ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 本文详细解析了客户端与服务器之间的交互过程,重点介绍了Socket通信机制。IP地址由32位的4个8位二进制数组成,分为网络地址和主机地址两部分。通过使用 `ipconfig /all` 命令,用户可以查看详细的IP配置信息。此外,文章还介绍了如何使用 `ping` 命令测试网络连通性,例如 `ping 127.0.0.1` 可以检测本机网络是否正常。这些技术细节对于理解网络通信的基本原理具有重要意义。 ... [详细]
  • 在机器学习领域,深入探讨了概率论与数理统计的基础知识,特别是这些理论在数据挖掘中的应用。文章重点分析了偏差(Bias)与方差(Variance)之间的平衡问题,强调了方差反映了不同训练模型之间的差异,例如在K折交叉验证中,不同模型之间的性能差异显著。此外,还讨论了如何通过优化模型选择和参数调整来有效控制这一平衡,以提高模型的泛化能力。 ... [详细]
  • 在C#编程中,数值结果的格式化展示是提高代码可读性和用户体验的重要手段。本文探讨了多种格式化方法和技巧,如使用格式说明符、自定义格式字符串等,以实现对数值结果的精确控制。通过实例演示,展示了如何灵活运用这些技术来满足不同的展示需求。 ... [详细]
  • 目前我有两张 BMP 图像文件 a.bmp 和 b.bmp,希望将它们按照以下方式进行融合:首先提取 a.bmp 的所有奇数行像素(如第 1、3、5 行),接着获取 b.bmp 的所有偶数行像素(如第 2、4、6 行)。最终目标是将这些行像素交替排列,生成一张新的图像。此过程需要确保像素顺序正确,并保持图像的整体结构和质量。 ... [详细]
  • PHP自学必备:从零开始的准备工作与工具选择 ... [详细]
author-avatar
月下小野
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有