CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tarojs--taro-h5

H5端API库,为Taro跨端开发框架提供Web/H5端的API实现

Pending
Overview
Eval results
Files

media.mddocs/

Media APIs

Comprehensive media handling capabilities including image selection, preview, information retrieval, and photo album integration for web-compatible media operations.

Capabilities

Image Selection APIs

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);
  }
};

Image Preview APIs

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'
]);

Image Information APIs

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;
  }
};

Photo Album Integration

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);
}

Implementation Status

✅ Fully Implemented

  • Image Selection: chooseImage - Complete implementation with album and camera support
  • Image Preview: previewImage - Full-screen preview with zoom and navigation
  • Image Information: getImageInfo - Complete dimension and format analysis
  • Photo Album: saveImageToPhotosAlbum - Full save functionality with permission handling

⚠️ Temporarily Not Supported

  • Image Processing: compressImage, editImage, cropImage - Return placeholder stubs
  • Media Preview: previewMedia - Advanced media preview functionality

❌ Permanently Not Supported

  • WeChat Specific: chooseMessageFile - Platform-specific file selection not available in browsers

Types

type 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

docs

canvas.md

core-framework.md

device.md

dom-query.md

index.md

location.md

media.md

navigation.md

network.md

storage.md

system-info.md

ui-interactions.md

tile.json