The Image Processing service provides specialized operations for images stored in OSS, including transformations, EXIF data extraction, style management, and format conversion through Alibaba Cloud's Image Processing service.
function ImageClient(options: ImageClientOptions): ImageClient;
interface ImageClientOptions {
region?: string;
accessKeyId: string;
accessKeySecret: string;
stsToken?: string;
bucket: string;
imageHost: string;
endpoint?: string;
timeout?: number | number[];
agent?: Agent;
httpsAgent?: Agent;
}const OSS = require('ali-oss');
// Create Image Client
const imgClient = OSS.ImageClient({
region: 'oss-cn-hangzhou',
accessKeyId: 'your-access-key-id',
accessKeySecret: 'your-access-key-secret',
bucket: 'your-image-bucket',
imageHost: 'img-cn-hangzhou.aliyuncs.com'
});async function get(name: string, file?: string, options?: ImageGetOptions): Promise<ImageGetResult>;
interface ImageGetOptions {
timeout?: number | number[];
headers?: Record<string, string>;
process?: string;
}
interface ImageGetResult {
content?: Buffer;
res: ResponseInfo;
size?: number;
aborted?: boolean;
rt?: number;
}async function getStream(name: string, options?: ImageGetOptions): Promise<ImageStreamResult>;
interface ImageStreamResult {
stream: ReadableStream;
res: ResponseInfo;
size?: number;
aborted?: boolean;
rt?: number;
}// Resize image to 200x200 pixels
const resized = await imgClient.get('photo.jpg', null, {
process: 'image/resize,w_200,h_200'
});
// Get thumbnail with quality adjustment
const thumbnail = await imgClient.get('large-image.jpg', null, {
process: 'image/resize,w_150,h_150/quality,q_80'
});
// Convert format and add watermark
const processed = await imgClient.get('source.png', null, {
process: 'image/format,jpg/watermark,text_V2F0ZXJtYXJr,size_20,x_10,y_10'
});
// Get processed image as stream
const stream = await imgClient.getStream('photo.jpg', {
process: 'image/resize,w_300,h_300/rotate,90'
});async function getInfo(name: string, options?: RequestOptions): Promise<ImageInfoResult>;
interface ImageInfoResult {
format: string;
width: number;
height: number;
size: number;
colorModel: string;
frameCount?: number;
res: ResponseInfo;
}async function getExif(name: string, options?: RequestOptions): Promise<ImageExifResult>;
interface ImageExifResult {
exif: ExifData;
res: ResponseInfo;
}
interface ExifData {
make?: string;
model?: string;
dateTime?: string;
orientation?: number;
xResolution?: string;
yResolution?: string;
resolutionUnit?: number;
software?: string;
[key: string]: any;
}// Get basic image information
const info = await imgClient.getInfo('photo.jpg');
console.log(`Image: ${info.width}x${info.height}, ${info.format}, ${info.size} bytes`);
// Extract EXIF data
const exifData = await imgClient.getExif('photo.jpg');
console.log('Camera:', exifData.exif.make, exifData.exif.model);
console.log('Date taken:', exifData.exif.dateTime);async function putStyle(styleName: string, style: ImageStyle, options?: RequestOptions): Promise<PutStyleResult>;
interface ImageStyle {
content: string;
}
interface PutStyleResult {
res: ResponseInfo;
}async function getStyle(styleName: string, options?: RequestOptions): Promise<GetStyleResult>;
interface GetStyleResult {
style: ImageStyle;
res: ResponseInfo;
}async function listStyle(options?: RequestOptions): Promise<ListStyleResult>;
interface ListStyleResult {
styles: StyleInfo[];
res: ResponseInfo;
}
interface StyleInfo {
name: string;
content: string;
createTime: Date;
lastModifyTime: Date;
}async function deleteStyle(styleName: string, options?: RequestOptions): Promise<DeleteStyleResult>;
interface DeleteStyleResult {
res: ResponseInfo;
}// Create a thumbnail style
await imgClient.putStyle('thumbnail', {
content: 'image/resize,w_200,h_200/quality,q_90'
});
// Create a watermark style
await imgClient.putStyle('watermark', {
content: 'image/watermark,text_Q29weXJpZ2h0,size_20,x_10,y_10,color_FFFFFF'
});
// List all styles
const styles = await imgClient.listStyle();
console.log('Available styles:', styles.styles.map(s => s.name));
// Use style in processing
const styled = await imgClient.get('photo.jpg', null, {
process: 'style/thumbnail'
});
// Delete style
await imgClient.deleteStyle('old-style');// Resize parameters
'image/resize,w_width,h_height' // Resize to specific dimensions
'image/resize,w_width' // Resize width, auto height
'image/resize,h_height' // Resize height, auto width
'image/resize,p_percentage' // Resize by percentage
'image/resize,w_width,h_height,m_mode' // Resize with mode
// Resize modes
'm_lfit' // Long side fit (default)
'm_mfit' // Short side fit
'm_fill' // Fill and crop
'm_pad' // Pad to fit
'm_fixed' // Force exact dimensions// Format conversion
'image/format,jpg' // Convert to JPEG
'image/format,png' // Convert to PNG
'image/format,webp' // Convert to WebP
'image/format,bmp' // Convert to BMP
'image/format,gif' // Convert to GIF
'image/format,tiff' // Convert to TIFF
// Quality adjustment (for JPEG/WebP)
'image/quality,q_80' // Set quality to 80%// Rotation
'image/rotate,90' // Rotate 90 degrees clockwise
'image/rotate,180' // Rotate 180 degrees
'image/rotate,270' // Rotate 270 degrees
// Auto-orient based on EXIF
'image/auto-orient,1' // Auto-orient image
// Brightness/Contrast
'image/bright,50' // Increase brightness by 50
'image/contrast,20' // Increase contrast by 20
// Sharpen/Blur
'image/sharpen,100' // Sharpen image
'image/blur,r_3,s_2' // Blur with radius 3, sigma 2// Crop operations
'image/crop,w_300,h_200,x_10,y_10' // Crop rectangle
'image/crop,w_300,h_200,g_center' // Crop from center
'image/indexcrop,x_10,y_10,w_100,h_100' // Index crop
// Crop gravity positions
'g_nw' // North West (top-left)
'g_n' // North (top-center)
'g_ne' // North East (top-right)
'g_w' // West (center-left)
'g_center' // Center
'g_e' // East (center-right)
'g_sw' // South West (bottom-left)
'g_s' // South (bottom-center)
'g_se' // South East (bottom-right)// Text watermark
'image/watermark,text_encoded_text,size_20,x_10,y_10,color_FFFFFF'
// Image watermark
'image/watermark,image_encoded_url,x_10,y_10,P_50'
// Watermark parameters
'size_20' // Font size
'color_FFFFFF' // Color in hex
'x_10' // X position
'y_10' // Y position
'P_50' // Transparency (0-100)
'g_center' // Gravity position// Complex processing pipeline
const complexProcess = [
'image/resize,w_800,h_600,m_lfit', // Resize
'image/rotate,90', // Rotate
'image/bright,10', // Brighten
'image/quality,q_85', // Quality
'image/format,jpg' // Convert format
].join('/');
const result = await imgClient.get('source.png', null, {
process: complexProcess
});// Process only if image is larger than 1000px
const conditionalProcess = 'image/resize,w_1000,h_1000,m_lfit/resize,w_800,h_600,m_lfit';
// Auto-format based on browser support
const autoFormat = 'image/format,webp'; // Falls back to original if not supportedfunction signatureUrl(name: string, options?: ImageSignatureOptions): string;
interface ImageSignatureOptions {
expires?: number;
process?: string;
}// Generate signed URL for processed image
const signedUrl = imgClient.signatureUrl('private-photo.jpg', {
expires: 3600, // 1 hour
process: 'image/resize,w_200,h_200/quality,q_90'
});
console.log('Temporary processed image URL:', signedUrl);try {
const result = await imgClient.get('photo.jpg', null, {
process: 'image/resize,w_2000,h_2000'
});
} catch (error) {
if (error.code === 'ImageTooLarge') {
console.error('Image dimensions exceed limits');
} else if (error.code === 'InvalidImageFormat') {
console.error('Unsupported image format');
} else {
console.error('Processing failed:', error.message);
}
}InvalidImageFormat - Unsupported image formatImageTooLarge - Image exceeds size limitsInvalidArgument - Invalid processing parametersProcessTimeout - Processing took too longInternalError - Internal processing error// Use appropriate quality settings
const webOptimized = 'image/resize,w_800,h_600/quality,q_85/format,webp';
// Cache processed images by using consistent naming
const cacheKey = `processed_${name}_${Buffer.from(process).toString('base64')}`;
// Use styles for frequently used transformations
await imgClient.putStyle('web-thumbnail', {
content: 'image/resize,w_300,h_300,m_fill/quality,q_90/format,webp'
});async function processObjectSave(sourceObject: string, targetObject: string, process: string, targetBucket?: string, options?: RequestOptions): Promise<ProcessObjectSaveResult>;
interface ProcessObjectSaveResult {
bucket: string;
fileSize: number;
imageInfo?: {
format: string;
width: number;
height: number;
};
object: string;
status: string;
res: ResponseInfo;
}// Process image and save result to new object
const result = await client.processObjectSave(
'photos/original.jpg', // Source object
'photos/thumbnail.jpg', // Target object
'image/resize,w_300,h_300/quality,q_85', // Processing parameters
'processed-images-bucket', // Optional: different target bucket
{ timeout: 30000 }
);
console.log('Processed image saved:');
console.log('Target:', result.object);
console.log('Size:', result.fileSize, 'bytes');
console.log('Dimensions:', `${result.imageInfo.width}x${result.imageInfo.height}`);
// Process with multiple transformations
const complexResult = await client.processObjectSave(
'uploads/photo.png',
'gallery/processed.jpg',
[
'image/resize,w_800,h_600,m_lfit', // Resize
'image/watermark,text_Q29weXJpZ2h0,size_20,x_10,y_10', // Watermark
'image/quality,q_90', // Quality
'image/format,jpg' // Convert format
].join('/')
);// Process multiple images
async function batchProcessImages(sourcePrefix, targetPrefix, processParams) {
// List source images
const list = await client.list({ prefix: sourcePrefix });
const results = [];
for (const obj of list.objects) {
if (obj.name.match(/\.(jpg|jpeg|png|gif)$/i)) {
try {
const targetName = obj.name.replace(sourcePrefix, targetPrefix);
const result = await client.processObjectSave(
obj.name,
targetName,
processParams,
null, // Same bucket
{ timeout: 60000 }
);
results.push({
source: obj.name,
target: targetName,
status: 'success',
size: result.fileSize
});
console.log(`Processed: ${obj.name} -> ${targetName}`);
} catch (error) {
console.error(`Failed to process ${obj.name}:`, error);
results.push({
source: obj.name,
status: 'failed',
error: error.message
});
}
}
}
return results;
}
// Usage
const batchResults = await batchProcessImages(
'uploads/',
'thumbnails/',
'image/resize,w_200,h_200,m_fill/quality,q_85'
);// Validate image dimensions before processing
const info = await imgClient.getInfo(imageName);
if (info.width > 5000 || info.height > 5000) {
throw new Error('Image too large for processing');
}
// Use signed URLs for private images
const privateUrl = imgClient.signatureUrl(privateName, {
expires: 1800, // 30 minutes
process: 'image/resize,w_200,h_200'
});