Image data objects in Javascript: Image, ImageData, and ImageBitmap


The front-end processes image data and provides several commonly used APIs, such as Image, ImageData, ImageBitmap, and so on. These objects can bring great help to us in manipulating pictures. Today we will introduce these useful object interfaces in detail.

Image

When processing images on the front end, the first API that comes to mind is Imagethe object .
Its main function is: it can load an image resource, create and return a new HTMLImageElementinstance , and have all the properties and events of the image element.
Constructor syntax: Image(width, height), with two parameters, representing the width and height attributes of the image.
Using it is also very simple, as follows:

const img = new Image()
img.src = 'chrome.png'

The above code defines an img object instance, and assigns an image link to the src attribute, so that the image resource can be loaded, and an image element object img can be obtained, and then width and height elements such as width and height of the image can be read.

Image object instances also have some commonly used properties and events, which we must understand:

  • Attributes: src, width, height, complete, alt, name, etc.
  • Events: onload, onerror, onabort, etc.

Image loads image resources in an asynchronous way. Generally, the image object instance is obtained in real time through onloadevent monitoring. Use Promisethe object for function encapsulation as follows:

const loadImage = (url) => {
    
    
  return new Promise((resolve, reject) => {
    
    
    const img = new Image()
    img.onload = () => {
    
    
      resolve(img)
    }
    img.onerror = (err) => {
    
    
      reject(err)
    }
    img.src = url
  })
}

The above code is the most common way to use Image, which was also mentioned in our previous blog post about image applications. In the previous blog post, the front-end image cropping function was implemented step by step , which is the way to load image resources.

src attribute, possible values:

  • local image path
  • web image link
  • Object-URL
  • Base64 image string

These methods of loading image resources are very common in current front-end development. Among them, for the knowledge of Object-URL and Base64, you can view the previous blog post: Detailed explanation of front-end binary knowledge and related API and Base64 knowledge .

It should be noted that the Image object is a Web-API, which depends on the browser environment; it is not a JS-API, and cannot be used in nodejs.

HTMLImageElement

As we know above, the Image constructor will return an HTMLImageElementinstance , which is loaded on the page and corresponds to a <img>tag element. A new img element instance can be obtained or generated in the following two ways.

  1. Get the img element of the page:
<img src="..." id="imgElm">
const img = document.getElementById('imgElm')
console.log(img.width)

In the above code, the page html defines an img element, and the corresponding element object can be obtained through the element id in JS.

  1. Create a new img element
const img = document.createElement('img')
img.onload = () => {
    
    
  document.body.append(img)
}
img.src = './logo.png'

In the above code, use document.createElement()the method to create a new image object, set the image resource, and display it on the page after loading.

It can be seen that document.createElement()the Image()method of using is almost the same as that of using , and the effect achieved is also similar. They both return a new HTMLImageElementobject instance.

Through a simple test comparison, the loading performance of a single or a small number of images is almostImage() the same as that of and can be used; but when loading image resources in large quantities, it is slightly faster than .createElement()Image()createElement()

In front-end commonly used image processing, <img>tags are used to load image resources, but they are slightly insufficient in various image operations, so canvascanvas , and the next two objects are canvasused in the environment.

ImageData

ImageDataThe object represents the pixel data for the area specified by canvasthe element .
The image pixel data is actually a color value, which can be represented by RGBAthe color model, so ImageDatathe pixel data of the object is the color value of each pixel of the image, and the length is windth * height * 44, where 4 is the corresponding RGBA4 color channels. Detailed knowledge of images can be found in the blog post Introduction to Basic Knowledge of Images .

Through the constructor, you can easily create object instances:

new ImageData(array, width, height);
new ImageData(width, height);

Parameter Description

  • array:
    It is an instance of Uint8ClampedArraythe type array, which stores the color value data of the pixels. The array elements RGBAare arranged in order according to the value of the 4 channels of each pixel. The length of the array must be windth * height * 4, otherwise an error will be reported.
    If this array parameter is not given, a fully transparent image will be created according to the width and height.
  • width: image width
  • height: image height

ImageDataThere are three object instance attributes: data, width, height.

const imgData = new ImageData(512, 512)
console.log(imgData)
// ImageData {data: Uint8ClampedArray(1048576), width: 512, height: 512, colorSpace: 'srgb'}
// data: Uint8ClampedArray(1048576) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …]

The above code defines a 512 * 512width height ImageData object instance. Through the output, you can see that the default value of pixel data is 0.

colorSpace: color space, can take two values srgb​​or display-p3, both are the color space of the RGB color model, some browsers do not support it.

For detailed knowledge of RGB colors, see the blog post Color models that the front end needs to know, RGB, HSL and HSV .

Uint8ClampedArray

The data parameters and properties of the ImageData object are instances of Uint8ClampedArraytype arrays, and Uint8ClampedArraywe also need to understand about them.
Uint8ClampedArray is an 8-bit unsigned integer fixed array, which belongs to one of 11 typed arrays (TypeArray), and the element value is fixed in the range of 0-255.
Its attribute parameters and usage are the same as other typed arrays. For a detailed introduction, see the blog post Front-end binary knowledge and related APIs .

Because of Uint8ClampedArray's unsigned and fixed characteristics, it is just right for storing the color value of a pixel. There are RGBAfour channels, and the value of each channel is a number between 0 and 255. Such as red, no transparency, [255, 0, 0, 255].
Notice:

  • Transparency generally uses 0 - 1interval , including color attributes in canvas 0 - 1. RGBThe values ​​of the three colors are basically consistent, ie 0 - 255.
  • The length of the image pixel point array must be 宽 * 高 * 4.

Application of ImageData in canvas

ImageData The image pixel object is based on the front-end canvas environment, and the application is also in the canvas operation, such as the creation method createImageData(), the reading method getImageData(), and the updating method putImageData().
These three methods are instance methods of the canvas drawing context, and we will introduce them one by one below.

createImageData()

createImageData() is used to create a brand new empty ImageData object, which returns pixel information data in the same way as ImageData()the constructor function.
Basic syntax:

context.createImageData(width, height)
context.createImageData(imagedata)

Create new objects by width and height, or other ImageData objects.

getImageData()

Returns some or all of the pixel information data in the canvas.
Basic grammar:

context.getImageData(sx, sy, sWidth, sHeight)

Parameter description:
sx: Return the starting abscissa of the image
sy: Return the starting ordinate of the image
sWidth: Return the width of the image
sHeight: Return the height of the image

putImageData()

Draw the specified ImageDataobject pixel data to the bitmap.
Basic grammar:

context.putImageData(imagedata, dx, dy [, dirtyX, [ dirtyY, [ dirtyWidth, [dirtyHeight]]]]);

Parameter description:
imagedata: image pixel information
dx: starting abscissa in the target canvas
dy: starting ordinate in the target canvas
dirtyX: abscissa of the upper left corner of the image data rendering area, optional
dirtyY: image data rendering The ordinate of the upper left corner of the area, optional
dirtyWidth: the width of the image data rendering area, optional
dirtyHeight: the height of the image data rendering area, optional

Practical application example

Among them, getImageData()and putImageData()are two essential methods for the front end to process images at the pixel level through canvas.
Next, let's look at a specific example.

First, we create a random function to take the color value and define a canvas element with a width and height of 100*100:

const randomRGB = () => Math.floor(Math.random() * (255 - 0) + 0)

const canvas = document.createElement('canvas')
canvas.width = 100
canvas.height = 100
document.body.append(canvas)

Next, we createImageData()define and assign values ​​to its elements. The R channel defaults to 255, and the BG channel takes a random value, and then use putImageData()to draw the pixel data:

const ctx = canvas.getContext('2d')
const imagedata = ctx.createImageData(100, 100)
const length = imagedata.data.length
for (let i = 0; i < length; i += 4) {
    
    
  imagedata.data[i] = 255
  imagedata.data[i + 1] = randomInRange()
  imagedata.data[i + 2] = randomInRange()
  imagedata.data[i + 3] = 255
}
ctx.putImageData(imagedata, 0, 0)

Finally, we use a 1s timer to getImageData()get pixel data, change the R channel of the color value to 0, and then redraw the image:

setTimeout(() => {
    
    
  const imgData = ctx.getImageData(0, 0, 100, 100)
  const len = imgData.data.length
  for (let i = 0; i < len; i += 4) {
    
    
    imgData.data[i] = 0
  }
  ctx.putImageData(imgData, 0, 0)
}, 1000)

The above code is to show the basic usage of pixel operation, there will be a process of image change, from red to green, as shown in the figure below:
insert image description here

ImageBitmap

In ImageDataaddition to , there is another object in canvas that can also be used to process image data, that is ImageBitmap.
ImageBitmapRepresents a bitmap image that can be drawn to a canvas and has low-latency features. Like
, they are global objects that can be accessed in the browser environment. Unlike , there is no constructor, and objects can be directly referenced (meaningless), but they cannot be created through constructors, but need to be .ImageData
ImageDataImageBitmapcreateImageBitmap()

// 直接引用对象,正常输出
ImageBitmap
// ƒ ImageBitmap() { [native code] }

// 函数调用,报错:非法构造函数
ImageBitmap()
// Uncaught TypeError: Illegal constructor

Properties and methods:

  • width: read-only, indicating the pixel width of the image
  • height: read-only, indicating the pixel height of the image
  • close(): Release all image resources associated with ImageBitmap

createImageBitmap()

createImageBitmap() accepts different image resources and returns a Promise asynchronous object whose successful result is ImageBitmap.
The basic syntax is as follows:

createImageBitmap(image[, options])
createImageBitmap(image, sx, sy, sw, sh[, options])

Basic parameter
image: image source
Possible values: img, SVG-image, video, canvas, HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement, Blob, File, ImageData, ImageBitmap, or OffscreenCanvas object sx: cropping starting point abscissa sy: clipping starting
point
vertical coordinates
sw: clipping width
sh: clipping height
options: optional, an object to set options for. Available options are:

imageOrientation: whether to render as it is or to flip vertically, optional none (default), flipY
premultiplyAlpha: whether the color channel is premultiplied by the alpha channel, optional none, premultiply, default (default)
colorSpaceConversion: whether to use color space conversion for decoding, optional none, default (default)
resizeWidth: new compression width
resizeHeight: new compression height
resizeQuality: compression quality, optional pixelated, low (default), medium, high
createImageBitmapcan directly read a variety of image data sources, such as ImageData, File, and more An HTML element object, etc., which allows us to process image data more flexibly.
Let's look at an example of reading a File object.

Example of use

The ImageBitmap object is mainly used as a parameter (image source) of the interface when using drawImage()the interface :

<input id="input-file" type="file" accept="image/*" multiple />

The above code first defines an input file upload control.

document.getElementById('input-file').onchange = (e) => {
    
    
  const file = e.target.files[0]
  createImageBitmap(file).then(imageBitmap => {
    
    
    const canvas = document.createElement('canvas')
    canvas.width = imageBitmap.width
    canvas.height = imageBitmap.height
    const ctx = canvas.getContext('2d')
    ctx.drawImage(imageBitmap, 0, 0)
    
    document.body.append(canvas)
  })
}

By listening to the control and reading the file stream object, createImageBitmap()you can directly read the file stream data and generate an ImageBitmap bitmap object. Create a canvas canvas object, use drawImage()to load the imageBitmap bitmap object, and the file can be directly drawn into the canvas and displayed.

おすすめ

転載: blog.csdn.net/jimojianghu/article/details/128700697