ImageUtils is a static utility class that wraps the Canvas adapter for common image operations. It is environment-agnostic: the same calls work in Node.js (CanvasKit), the browser (HTMLCanvasElement), and Web Workers (OffscreenCanvas).
ImageType
ImageType is an enum listing the image formats supported by GeoPackage JS.
import { ImageType } from '@ngageoint/geopackage';
enum ImageType {
PNG = 'png',
JPEG = 'jpeg',
JPG = 'jpg',
TIFF = 'tiff',
WEBP = 'webp',
}
ImageType.getMimeType()
Converts an ImageType value to its MIME type string.
ImageType.getMimeType(type?: ImageType): string
The image type to convert. Defaults to ImageType.PNG.
ImageType.getMimeType(ImageType.JPEG); // 'image/jpeg'
ImageType.getMimeType(ImageType.PNG); // 'image/png'
ImageType.getTypeFromMimeType()
Converts a MIME type string back to an ImageType enum value.
ImageType.getTypeFromMimeType(mimeType: string): ImageType
A MIME type string such as 'image/png' or 'image/jpeg'.
Throws GeoPackageException if the MIME type is not recognised.
Static methods
getImage()
Loads raw image bytes, a base64 data URL, or a file path into a GeoPackageImage. If the value passed is already a GeoPackageImage it is returned unchanged.
public static async getImage(
data: Uint8Array | Buffer | string,
contentType?: string
): Promise<GeoPackageImage>
data
Uint8Array | Buffer | string
required
Raw image bytes, a base64 data URL string, a file path (Node.js), or an existing GeoPackageImage.
MIME type of the image data. Defaults to 'image/png'.
Returns null if decoding fails rather than throwing, so always check the return value.
import { ImageUtils, ImageType } from '@ngageoint/geopackage';
import fs from 'fs';
const bytes = fs.readFileSync('/data/tile.png');
const image = await ImageUtils.getImage(bytes, 'image/png');
if (image) {
console.log(`${image.getWidth()}x${image.getHeight()}`);
image.dispose(); // free CanvasKit memory in Node.js
}
getImageSize()
Returns the pixel dimensions of an image from its raw bytes or file path without fully decoding it. This is a synchronous operation backed by the image-size library.
public static getImageSize(
data: Buffer | string
): ISizeCalculationResult
Raw image bytes (Buffer) or a file path (string).
Returns an ISizeCalculationResult with width, height, and type properties.
import { ImageUtils } from '@ngageoint/geopackage';
import fs from 'fs';
const bytes = fs.readFileSync('/data/tile.png');
const { width, height, type } = ImageUtils.getImageSize(bytes);
console.log(width, height, type); // 256 256 'png'
getScaledImage()
Loads an image from bytes or a file path and returns a new GeoPackageImage scaled by the given factor. If scale is exactly 1.0 the original image is returned without re-encoding.
public static async getScaledImage(
data: Buffer | string,
scale: number
): Promise<GeoPackageImage>
Raw image bytes or a file path.
Uniform scale factor. 0.5 halves both dimensions; 2 doubles them.
Returns null if the image could not be loaded or scaled.
The original image is automatically disposed after scaling. Only the returned scaled image needs to be disposed.
import { ImageUtils } from '@ngageoint/geopackage';
import fs from 'fs';
const bytes = fs.readFileSync('/data/tile.png');
const scaled = await ImageUtils.getScaledImage(bytes, 0.5);
if (scaled) {
console.log(`${scaled.getWidth()}x${scaled.getHeight()}`);
scaled.dispose();
}
scaleImage()
Scales an existing GeoPackageImage to exact pixel dimensions. The source image is automatically disposed.
public static async scaleImage(
image: GeoPackageImage,
scaledWidth: number,
scaledHeight: number
): Promise<GeoPackageImage>
The source image. Do not use this image after the call — it is disposed internally.
Returns null if scaling fails.
image is disposed inside scaleImage(). Do not call image.dispose() yourself after passing it to this method.
import { ImageUtils } from '@ngageoint/geopackage';
// image was obtained from Canvas.createImage() or a tile retriever
const thumbnail = await ImageUtils.scaleImage(image, 64, 64);
if (thumbnail) {
// use thumbnail...
thumbnail.dispose();
}
writeImageToBytes()
Encodes a GeoPackageImage to a Uint8Array in the specified format.
public static async writeImageToBytes(
image: GeoPackageImage,
imageFormat: ImageType,
compressionQuality: number
): Promise<Uint8Array>
Target format, e.g. ImageType.PNG or ImageType.JPEG.
Quality from 0 to 1. Only meaningful for lossy formats such as ImageType.JPEG. Pass 1.0 for lossless formats.
import { ImageUtils, ImageType } from '@ngageoint/geopackage';
import fs from 'fs';
const bytes = await ImageUtils.writeImageToBytes(image, ImageType.JPEG, 0.85);
fs.writeFileSync('/output/tile.jpg', bytes);
image.dispose();
isFullyTransparent()
Checks whether every pixel in the image is fully transparent (alpha = 0). Useful for skipping blank tiles.
public static async isFullyTransparent(
data: Uint8Array | Buffer,
width: number,
height: number
): Promise<boolean>
data
Uint8Array | Buffer
required
Raw image bytes.
Expected image width in pixels.
Expected image height in pixels.
Returns true if all pixels are fully transparent, false otherwise.
import { ImageUtils } from '@ngageoint/geopackage';
const blank = await ImageUtils.isFullyTransparent(tileBytes, 256, 256);
if (!blank) {
// render the tile
}
Complete example
The following example shows a typical Node.js workflow: load a tile from a GeoPackage, scale it to a thumbnail size, encode it as JPEG, and save it to disk.
import {
GeoPackageManager,
GeoPackageTileRetriever,
ImageUtils,
ImageType,
} from '@ngageoint/geopackage';
import fs from 'fs';
const geoPackage = await GeoPackageManager.open('/data/world.gpkg');
try {
const retriever = new GeoPackageTileRetriever(geoPackage, 'tiles', 256, 256);
const tileBytes = await retriever.getTileData(0, 0, 0);
if (tileBytes) {
// Decode bytes into a GeoPackageImage
const image = await ImageUtils.getImage(tileBytes, 'image/png');
if (image && !(await ImageUtils.isFullyTransparent(tileBytes, image.getWidth(), image.getHeight()))) {
// Scale to 64x64 thumbnail (disposes original image internally)
const thumb = await ImageUtils.scaleImage(image, 64, 64);
if (thumb) {
const jpegBytes = await ImageUtils.writeImageToBytes(thumb, ImageType.JPEG, 0.9);
fs.writeFileSync('/output/thumb.jpg', jpegBytes);
thumb.dispose();
}
} else {
image?.dispose();
}
}
} finally {
geoPackage.close();
}