H5端API库,为Taro跨端开发框架提供Web/H5端的API实现
—
Comprehensive media handling capabilities including image selection, preview, information retrieval, and photo album integration for web-compatible media operations.
File selection and camera integration for capturing or choosing images from user device.
/**
* Select images from album or take photos using camera
* @deprecated Use chooseMedia interface instead for better functionality
* @param options - Image selection configuration options
* @returns Promise resolving to selected image information
*/
function chooseImage(options: ChooseImageOption): Promise<ChooseImageResult>;
interface ChooseImageOption {
/** Maximum number of images to select (default: 9) */
count?: number;
/** Image size type preference */
sizeType?: ('original' | 'compressed')[];
/** Image source types */
sourceType?: ('album' | 'camera' | 'user')[];
/** Success callback function */
success?: (result: ChooseImageResult) => void;
/** Failure callback function */
fail?: (error: any) => void;
/** Completion callback function */
complete?: (result: ChooseImageResult | any) => void;
}
interface ChooseImageResult {
/** Array of selected image file paths */
tempFilePaths: string[];
/** Detailed information about selected images */
tempFiles: ImageFile[];
/** Operation result message */
errMsg: string;
}
interface ImageFile {
/** Temporary file path (blob URL) */
path: string;
/** File size in bytes */
size: number;
/** File type/format */
type: string;
/** Original File object for advanced operations */
originalFileObj?: File;
}Usage Examples:
import { chooseImage } from "@tarojs/taro-h5";
// Basic image selection
const selectImages = async () => {
try {
const result = await chooseImage({
count: 3,
sizeType: ['compressed'],
sourceType: ['album', 'camera']
});
console.log('Selected images:', result.tempFilePaths);
// Display selected images
result.tempFilePaths.forEach((imagePath, index) => {
const img = document.createElement('img');
img.src = imagePath;
img.style.maxWidth = '200px';
img.style.margin = '10px';
document.body.appendChild(img);
});
// Get detailed file information
result.tempFiles.forEach((file, index) => {
console.log(`Image ${index + 1}:`);
console.log(`- Path: ${file.path}`);
console.log(`- Size: ${(file.size / 1024).toFixed(2)} KB`);
console.log(`- Type: ${file.type}`);
});
} catch (error) {
console.error('Image selection failed:', error);
}
};
// Camera-only selection
const takePhoto = async () => {
try {
const result = await chooseImage({
count: 1,
sourceType: ['camera'],
sizeType: ['original'],
success: (res) => {
console.log('Photo captured successfully');
},
fail: (error) => {
console.error('Camera access failed:', error);
}
});
const photoPath = result.tempFilePaths[0];
// Use the captured photo
const img = document.createElement('img');
img.src = photoPath;
img.style.maxWidth = '100%';
document.getElementById('photo-container')?.appendChild(img);
} catch (error) {
console.error('Photo capture failed:', error);
}
};
// Multiple image selection with validation
const selectValidatedImages = async () => {
try {
const result = await chooseImage({
count: 5,
sourceType: ['album'],
sizeType: ['compressed']
});
// Validate selected images
const validImages = result.tempFiles.filter(file => {
// Check file size (max 5MB)
if (file.size > 5 * 1024 * 1024) {
console.warn(`Image too large: ${file.path}`);
return false;
}
// Check file type
const validTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (!validTypes.includes(file.type)) {
console.warn(`Invalid image type: ${file.type}`);
return false;
}
return true;
});
if (validImages.length === 0) {
throw new Error('No valid images selected');
}
console.log(`Selected ${validImages.length} valid images`);
return validImages.map(file => file.path);
} catch (error) {
console.error('Image validation failed:', error);
}
};Full-screen image preview with swipe navigation and zoom functionality.
/**
* Preview images in full-screen with navigation and zoom support
* @param options - Image preview configuration options
* @returns Promise resolving when preview is initialized
*/
function previewImage(options: PreviewImageOption): Promise<void>;
interface PreviewImageOption {
/** Current image URL to display initially */
current?: string | number;
/** Array of image URLs to preview */
urls: string[];
/** Success callback function */
success?: () => void;
/** Failure callback function */
fail?: (error: any) => void;
/** Completion callback function */
complete?: () => void;
}Usage Examples:
import { previewImage } from "@tarojs/taro-h5";
// Basic image preview
const previewGallery = async () => {
const imageUrls = [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg'
];
try {
await previewImage({
current: 0, // Start with first image
urls: imageUrls,
success: () => {
console.log('Image preview opened');
},
fail: (error) => {
console.error('Preview failed:', error);
}
});
} catch (error) {
console.error('Failed to open image preview:', error);
}
};
// Preview with specific starting image
const previewFromCurrent = async (currentImageUrl: string, allImages: string[]) => {
try {
await previewImage({
current: currentImageUrl, // Start with specific image
urls: allImages,
success: () => {
console.log('Preview started from:', currentImageUrl);
}
});
} catch (error) {
console.error('Preview initialization failed:', error);
}
};
// Gallery component integration
class ImageGallery {
private images: string[] = [];
constructor(imageUrls: string[]) {
this.images = imageUrls;
this.createGalleryUI();
}
private createGalleryUI() {
const container = document.createElement('div');
container.className = 'image-gallery';
container.style.cssText = 'display: flex; flex-wrap: wrap; gap: 10px; padding: 20px;';
this.images.forEach((imageUrl, index) => {
const thumbnail = document.createElement('img');
thumbnail.src = imageUrl;
thumbnail.style.cssText = 'width: 150px; height: 150px; object-fit: cover; cursor: pointer; border-radius: 8px;';
// Add click handler for preview
thumbnail.addEventListener('click', () => {
this.openPreview(index);
});
container.appendChild(thumbnail);
});
document.body.appendChild(container);
}
private async openPreview(startIndex: number) {
try {
await previewImage({
current: startIndex,
urls: this.images,
success: () => {
console.log(`Opened preview starting at image ${startIndex + 1}`);
}
});
} catch (error) {
console.error('Gallery preview failed:', error);
}
}
// Add images to gallery
addImages(newImages: string[]) {
this.images.push(...newImages);
// Refresh UI
const existingGallery = document.querySelector('.image-gallery');
existingGallery?.remove();
this.createGalleryUI();
}
}
// Usage
const gallery = new ImageGallery([
'https://example.com/photo1.jpg',
'https://example.com/photo2.jpg',
'https://example.com/photo3.jpg'
]);Retrieve detailed information about images including dimensions and format data.
/**
* Get detailed image information including dimensions and format
* @param options - Image information retrieval options
* @returns Promise resolving to image information
*/
function getImageInfo(options: GetImageInfoOption): Promise<ImageInfoResult>;
interface GetImageInfoOption {
/** Image URL or path to analyze */
src: string;
/** Success callback function */
success?: (result: ImageInfoResult) => void;
/** Failure callback function */
fail?: (error: any) => void;
/** Completion callback function */
complete?: (result: ImageInfoResult | any) => void;
}
interface ImageInfoResult {
/** Image width in pixels */
width: number;
/** Image height in pixels */
height: number;
/** Base64 data URL or original path */
path: string;
}Usage Examples:
import { getImageInfo } from "@tarojs/taro-h5";
// Get basic image information
const analyzeImage = async (imageUrl: string) => {
try {
const info = await getImageInfo({
src: imageUrl,
success: (result) => {
console.log('Image analysis completed');
},
fail: (error) => {
console.error('Image analysis failed:', error);
}
});
console.log('Image Information:');
console.log(`- Dimensions: ${info.width} x ${info.height} pixels`);
console.log(`- Aspect Ratio: ${(info.width / info.height).toFixed(2)}`);
console.log(`- Data Path: ${info.path.substring(0, 50)}...`);
return info;
} catch (error) {
console.error('Failed to get image info:', error);
throw error;
}
};
// Batch image analysis
const analyzeBatchImages = async (imageUrls: string[]) => {
try {
const analysisPromises = imageUrls.map(async (url, index) => {
try {
const info = await getImageInfo({ src: url });
return {
index,
url,
success: true,
info
};
} catch (error) {
return {
index,
url,
success: false,
error: error.message
};
}
});
const results = await Promise.all(analysisPromises);
// Process results
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`Analysis completed: ${successful.length} successful, ${failed.length} failed`);
successful.forEach((result, index) => {
if (result.success) {
const { info } = result;
console.log(`Image ${result.index + 1}: ${info.width}x${info.height}`);
}
});
if (failed.length > 0) {
console.error('Failed images:', failed.map(f => f.url));
}
return results;
} catch (error) {
console.error('Batch analysis failed:', error);
}
};
// Image validation using getImageInfo
const validateImageDimensions = async (imageUrl: string, requirements: { minWidth?: number; minHeight?: number; maxWidth?: number; maxHeight?: number; aspectRatio?: number }) => {
try {
const info = await getImageInfo({ src: imageUrl });
const errors: string[] = [];
if (requirements.minWidth && info.width < requirements.minWidth) {
errors.push(`Width ${info.width} is less than required ${requirements.minWidth}`);
}
if (requirements.maxWidth && info.width > requirements.maxWidth) {
errors.push(`Width ${info.width} exceeds maximum ${requirements.maxWidth}`);
}
if (requirements.minHeight && info.height < requirements.minHeight) {
errors.push(`Height ${info.height} is less than required ${requirements.minHeight}`);
}
if (requirements.maxHeight && info.height > requirements.maxHeight) {
errors.push(`Height ${info.height} exceeds maximum ${requirements.maxHeight}`);
}
if (requirements.aspectRatio) {
const actualRatio = info.width / info.height;
const tolerance = 0.1; // 10% tolerance
const expectedRatio = requirements.aspectRatio;
if (Math.abs(actualRatio - expectedRatio) > tolerance) {
errors.push(`Aspect ratio ${actualRatio.toFixed(2)} does not match required ${expectedRatio}`);
}
}
return {
valid: errors.length === 0,
errors,
info
};
} catch (error) {
return {
valid: false,
errors: [`Failed to analyze image: ${error.message}`],
info: null
};
}
};
// Usage example
const validateProfileImage = async (imageUrl: string) => {
const validation = await validateImageDimensions(imageUrl, {
minWidth: 200,
minHeight: 200,
maxWidth: 1024,
maxHeight: 1024,
aspectRatio: 1.0 // Square images
});
if (validation.valid) {
console.log('Image meets requirements');
return true;
} else {
console.error('Image validation failed:', validation.errors);
return false;
}
};Save images to device photo album with permission handling.
/**
* Save image to device photo album
* @param options - Save image configuration options
* @returns Promise resolving when save operation completes
*/
function saveImageToPhotosAlbum(options: SaveImageOption): Promise<void>;
interface SaveImageOption {
/** Image file path to save */
filePath: string;
/** Success callback function */
success?: () => void;
/** Failure callback function */
fail?: (error: any) => void;
/** Completion callback function */
complete?: () => void;
}Usage Examples:
import { saveImageToPhotosAlbum } from "@tarojs/taro-h5";
// Save single image to photos album
const saveToAlbum = async (imagePath: string) => {
try {
await saveImageToPhotosAlbum({
filePath: imagePath,
success: () => {
console.log('Image saved to album successfully');
showSuccessMessage('Image saved to photos');
},
fail: (error) => {
console.error('Save to album failed:', error);
showErrorMessage('Failed to save image');
}
});
} catch (error) {
console.error('Save operation failed:', error);
}
};
// Save multiple images with progress tracking
const saveMultipleImages = async (imagePaths: string[]) => {
let savedCount = 0;
let failedCount = 0;
const savePromises = imagePaths.map(async (imagePath, index) => {
try {
await saveImageToPhotosAlbum({
filePath: imagePath,
success: () => {
savedCount++;
console.log(`Image ${index + 1} saved successfully`);
updateProgress(savedCount + failedCount, imagePaths.length);
},
fail: (error) => {
failedCount++;
console.error(`Failed to save image ${index + 1}:`, error);
updateProgress(savedCount + failedCount, imagePaths.length);
}
});
} catch (error) {
failedCount++;
console.error(`Exception saving image ${index + 1}:`, error);
}
});
try {
await Promise.all(savePromises);
console.log(`Save completed: ${savedCount} successful, ${failedCount} failed`);
if (savedCount > 0) {
showSuccessMessage(`${savedCount} images saved to album`);
}
if (failedCount > 0) {
showErrorMessage(`${failedCount} images failed to save`);
}
} catch (error) {
console.error('Batch save operation failed:', error);
}
};
// Helper functions for UI feedback
function updateProgress(completed: number, total: number) {
const percent = Math.round((completed / total) * 100);
console.log(`Progress: ${completed}/${total} (${percent}%)`);
// Update progress bar if available
const progressBar = document.getElementById('save-progress');
if (progressBar) {
progressBar.style.width = `${percent}%`;
}
}
function showSuccessMessage(message: string) {
// Implementation would show toast or notification
console.log('Success:', message);
}
function showErrorMessage(message: string) {
// Implementation would show error toast or notification
console.error('Error:', message);
}chooseImage - Complete implementation with album and camera supportpreviewImage - Full-screen preview with zoom and navigationgetImageInfo - Complete dimension and format analysissaveImageToPhotosAlbum - Full save functionality with permission handlingcompressImage, editImage, cropImage - Return placeholder stubspreviewMedia - Advanced media preview functionalitychooseMessageFile - Platform-specific file selection not available in browserstype ImageSourceType = 'album' | 'camera' | 'user';
type ImageSizeType = 'original' | 'compressed';
interface MediaCapabilities {
/** Whether device supports camera access */
camera: boolean;
/** Whether device supports album access */
album: boolean;
/** Whether device supports photo album saving */
saveToAlbum: boolean;
}
// Get device media capabilities
declare function getMediaCapabilities(): MediaCapabilities;Install with Tessl CLI
npx tessl i tessl/npm-tarojs--taro-h5