just_image 1.0.0 copy "just_image: ^1.0.0" to clipboard
just_image: ^1.0.0 copied to clipboard

High-performance image processing engine powered by Rust FFI. Supports AVIF, WebP, JPEG, PNG, TIFF, BMP with zero-copy memory, SIMD acceleration, and professional metadata preservation.

example/just_image_example.dart

// ignore_for_file: unused_local_variable
/// Ejemplo completo de just_image: procesamiento de imágenes con el motor Rust nativo.
///
/// Antes de ejecutar, genera las imágenes de prueba:
///   dart run example/create_test_images.dart
///
/// Luego ejecuta el ejemplo:
///   dart run example/just_image_example.dart
///
/// NOTA: Requiere que la librería nativa esté compilada:
///   cd native && cargo build --release
library;

import 'dart:io';

import 'package:just_image/just_image.dart';

Future<void> main() async {
  final imgDir = 'example/images';
  final outDir = 'example/output';
  Directory(outDir).createSync(recursive: true);

  // Verificar que las imágenes de prueba existen
  final gradientFile = File('$imgDir/gradient.bmp');
  if (!gradientFile.existsSync()) {
    print('⚠ No se encontraron imágenes de prueba.');
    print('  Ejecuta primero: dart run example/create_test_images.dart');
    return;
  }

  print('═══════════════════════════════════════');
  print('  just_image — Ejemplo de procesamiento');
  print('═══════════════════════════════════════\n');

  // ─────────────────────────────────────
  // 1. Pipeline fluido básico: resize + sharpen + cambio de formato
  // ─────────────────────────────────────
  print('1. Pipeline básico: resize + sharpen → JPEG');
  final gradientBytes = gradientFile.readAsBytesSync();

  final result = await ImagePipeline(gradientBytes)
      .resize(100, 75)
      .sharpen(1.5)
      .toFormat(ImageFormat.jpeg)
      .quality(85)
      .execute();

  File('$outDir/01_resized.jpg').writeAsBytesSync(result.data);
  print(
    '   → ${result.width}x${result.height}, '
    '${result.sizeInBytes} bytes\n',
  );

  // ─────────────────────────────────────
  // 2. Motor de alto nivel: procesamiento rápido
  // ─────────────────────────────────────
  print('2. Engine quick process: landscape → WebP thumbnail');
  final engine = JustImageEngine();
  print('   Versión nativa: ${engine.nativeVersion}');

  final landscapeBytes = File('$imgDir/landscape.bmp').readAsBytesSync();
  final thumb = await engine.process(
    landscapeBytes,
    width: 160,
    height: 120,
    format: ImageFormat.webp,
    quality: 80,
  );

  File('$outDir/02_thumb.webp').writeAsBytesSync(thumb.data);
  print('   → ${thumb.width}x${thumb.height}, ${thumb.sizeInBytes} bytes\n');

  // ─────────────────────────────────────
  // 3. Pipeline completo con múltiples efectos
  // ─────────────────────────────────────
  print(
    '3. Pipeline pro: crop + resize + HSL + brightness + contrast + sharpen',
  );
  final checkerBytes = File('$imgDir/checkerboard.bmp').readAsBytesSync();
  final watermarkBytes = File('$imgDir/watermark.bmp').readAsBytesSync();

  final pro = await engine
      .load(checkerBytes)
      .autoOrient(true)
      .preserveMetadata(true)
      .crop(10, 10, 140, 140)
      .resize(200, 200)
      .hsl(hue: 15, saturation: 0.1, lightness: 0.05)
      .brightness(0.05)
      .contrast(0.15)
      .sharpen(1.2, 0.5)
      .watermark(watermarkBytes, x: 60, y: 80, opacity: 0.5)
      .toFormat(ImageFormat.png)
      .execute();

  File('$outDir/03_pro.png').writeAsBytesSync(pro.data);
  print('   → ${pro.width}x${pro.height}, ${pro.sizeInBytes} bytes\n');

  // ─────────────────────────────────────
  // 4. Efectos individuales
  // ─────────────────────────────────────
  final circlesBytes = File('$imgDir/circles.bmp').readAsBytesSync();

  // 4a. Gaussian Blur
  print('4a. Efecto: Gaussian Blur (σ=3.0)');
  final blurred = await ImagePipeline(
    circlesBytes,
  ).blur(3.0).toFormat(ImageFormat.png).execute();
  File('$outDir/04a_blur.png').writeAsBytesSync(blurred.data);
  print('   → ${blurred.width}x${blurred.height}\n');

  // 4b. Detección de bordes (Sobel)
  print('4b. Efecto: Detección de bordes Sobel');
  final edges = await ImagePipeline(
    circlesBytes,
  ).sobel().toFormat(ImageFormat.png).execute();
  File('$outDir/04b_edges.png').writeAsBytesSync(edges.data);
  print('   → ${edges.width}x${edges.height}\n');

  // 4c. Rotación libre (45°)
  print('4c. Transformación: Rotación 45°');
  final rotated = await ImagePipeline(
    gradientBytes,
  ).rotate(45).toFormat(ImageFormat.png).execute();
  File('$outDir/04c_rotated.png').writeAsBytesSync(rotated.data);
  print('   → ${rotated.width}x${rotated.height}\n');

  // 4d. Flip horizontal
  print('4d. Transformación: Flip horizontal');
  final flipped = await ImagePipeline(
    gradientBytes,
  ).flip(FlipDirection.horizontal).toFormat(ImageFormat.bmp).execute();
  File('$outDir/04d_flipped.bmp').writeAsBytesSync(flipped.data);
  print('   → ${flipped.width}x${flipped.height}\n');

  // 4e. Ajuste de brillo
  print('4e. Efecto: Brillo +30%');
  final bright = await ImagePipeline(
    landscapeBytes,
  ).brightness(0.3).toFormat(ImageFormat.png).execute();
  File('$outDir/04e_bright.png').writeAsBytesSync(bright.data);
  print('   → ${bright.width}x${bright.height}\n');

  // ─────────────────────────────────────
  // 5. Batch Processing con prioridades
  // ─────────────────────────────────────
  print('5. Batch processing: 3 imágenes en paralelo');
  final batch = engine.createBatch(concurrency: 3);

  final inputImages = [gradientBytes, landscapeBytes, circlesBytes];

  final futures = inputImages.map(
    (bytes) => batch.enqueue(
      ImagePipeline(
        bytes,
      ).resize(80, 60).sharpen(0.8).toFormat(ImageFormat.webp).quality(75),
      priority: TaskPriority.normal,
    ),
  );

  final batchResults = await Future.wait(futures);
  for (var i = 0; i < batchResults.length; i++) {
    File('$outDir/05_batch_$i.webp').writeAsBytesSync(batchResults[i].data);
  }
  print('   → ${batchResults.length} imágenes procesadas\n');

  // Tarea de alta prioridad
  print('   Tarea crítica: thumbnail urgente');
  final urgent = await batch.enqueue(
    ImagePipeline(gradientBytes).resize(32, 32).toFormat(ImageFormat.png),
    priority: TaskPriority.critical,
  );
  File('$outDir/05_urgent.png').writeAsBytesSync(urgent.data);
  print('   → ${urgent.width}x${urgent.height}\n');

  // ─────────────────────────────────────
  // 6. Conversión entre formatos
  // ─────────────────────────────────────
  print('6. Conversión de formatos: BMP → JPEG, PNG, WebP');
  for (final fmt in [ImageFormat.jpeg, ImageFormat.png, ImageFormat.webp]) {
    final converted = await ImagePipeline(
      gradientBytes,
    ).toFormat(fmt).quality(90).execute();
    final ext = fmt.value;
    File('$outDir/06_converted.$ext').writeAsBytesSync(converted.data);
    print('   → $ext: ${converted.sizeInBytes} bytes');
  }

  print('\n═══════════════════════════════════════');
  print('  ✅ Todos los ejemplos completados');
  print('  📂 Resultados en: $outDir/');
  print('═══════════════════════════════════════');

  engine.dispose();
}
1
likes
0
points
177
downloads

Publisher

unverified uploader

Weekly Downloads

High-performance image processing engine powered by Rust FFI. Supports AVIF, WebP, JPEG, PNG, TIFF, BMP with zero-copy memory, SIMD acceleration, and professional metadata preservation.

Repository (GitHub)
View/report issues

Topics

#image #image-processing #ffi #rust

License

unknown (license)

Dependencies

ffi, logging, native_assets_cli

More

Packages that depend on just_image