这是这个问题的重复:Get image width and height from the Base64 code in JavaScript,但我问的是关于德诺的事情.Deno没有我读过的所有解决方案中使用的new Image().我打算在边缘函数中做到这一点,因此减少依赖性是很重要的.以下是我考虑过的一些事情:

有没有一种方法可以在没有包的情况下做到这一点,或者只需要使用一些内置的包就可以做到呢?

推荐答案

为了在没有外部库的情况下获得图像的宽度和高度,您需要解析图像标题.如果您只处理几种图像类型,您可以很容易地避免使用第三方库.

例如,要从Base64编码的图像中解析PNG图像的宽度和高度,您可以这样做:

import { decode } from "https://deno.land/std/encoding/base64.ts"

const pngImageb64 = /* some png image in base64 */

const pngImage = decode(pngImageb64);
const dataView = new DataView(pngImage.buffer);
// The width and height are 4-byte integers starting 
// at byte offset 16 and 20, respectively.
const width = dataView.getUint32(16);
const height = dataView.getUint32(20);

参考文献:http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html

宽度和高度提供以像素为单位的图像尺寸.它们是4字节的 整数.零是无效值.每个的最大值是2^31


对于jpeg,这有点困难,因为维度存储在帧开始(SOF)标记中.以下代码应该适用于大多数情况(仅在几个jpeg中进行了测试)

const jpegImageb64 = /* some jpeg image in base64 */

const jpegImage = decode(jpegImageb64);
const dataView = new DataView(jpegImage.buffer);

let width, height;
for (let i = 0; i < dataView.byteLength - 9; i++) {  // - 9 prevent out-of-bounds access
    if (dataView.getUint16(i) === 0xFFC0 || dataView.getUint16(i) === 0xFFC2) {
      height = dataView.getUint16(i + 5);
      width = dataView.getUint16(i + 7);
      break;
  }
}

其他可能的解决方案:


为了检测图像类型,以便您知道使用哪个解析器,您必须读取图像的第一个字节,您可以使用file-type lib(在解码base64之后)

自己检测jpeg请参见https://github.com/sindresorhus/file-type/blob/5c42f8057f056fe41cbe4bffb53f56987d02e909/core.js#L238-L249.


根据您处理的图像类型的不同,它可能会更加复杂,如果您支持多种图像格式,我建议您使用诸如sharp这样的库来解析数据.

Typescript相关问答推荐

如何在同一页面中使用布局和提供程序?

物料UI图表仅在悬停后加载行

接口DOMRouter选项未输出

定义JMX的类型:类型上不存在属性键

如何将绑定到实例的类方法复制到类型脚本中的普通对象?

当我点击外部按钮时,如何打开Html Select 选项菜单?

如何在typescript中设置对象分配时的键类型和值类型

在不更改类型签名的情况下在数组并集上映射文字

通过按键数组拾取对象的关键点

为什么我的一个合成函数不能推断类型?

按函数名的类型安全类型脚本方法包装帮助器

如何缩小函数的返回类型?

类型';字符串|数字';不可分配给类型';未定义';.类型';字符串';不可分配给类型';未定义';

如何避免从引用<;字符串&>到引用<;字符串|未定义&>;的不安全赋值?

回调函数中的TypeScrip类型保护返回Incorect类型保护(具有其他未定义类型的返回保护类型)

如何在不违反挂钩规则的情况下动态更改显示内容(带有状态)?

如何创建一个将嵌套类属性的点表示法生成为字符串文字的类型?

如何使用警告实现`RecursiveReadonly<;T>;`,如果`T`是原语,则返回`T`而不是`RecursiveReadonly<;T>;`

如何限定索引值必须与相应属性的id字段相同

如何使用 runInInjectionContext 中的参数测试功能性路由防护