Guía completa de Flutter: El widget Image


Avatar de Pedro Cortez

Mostrar imágenes es esencial en el diseño de una aplicación Flutter dinámica. En esta guía, aprende cómo integrar diferentes tipos de imágenes y optimizar su tiempo de carga.


widget image flutter

Introducción al widget Image

El widget Image es un componente básico de Flutter que te permite mostrar ilustraciones e imágenes en tu aplicación móvil. Este widget admite varias formas de integrar contenido desde diferentes fuentes:

  • Archivos locales (imágenes almacenadas en los recursos de la aplicación)
  • URL (imágenes obtenidas en línea)
  • Memoria (imágenes almacenadas directamente en la memoria)
  • Sistema de archivos (imágenes provenientes del almacenamiento local del dispositivo)

¿Qué formatos de imagen están permitidos?

lutter es compatible con muchos formatos de imagen, tanto estáticos como animados, para equilibrar estética y rendimiento. Estos son los principales formatos de imagen que se pueden usar con el widget Image:

  • JPEG: Formato comprimido que reduce la calidad, pero disminuye el tamaño del archivo.
  • PNG: Formato comprimido sin pérdida, que permite tener un fondo transparente.
  • GIF: Formato de imagen animada que permite almacenar secuencias de imágenes en un solo archivo.
  • WEBP: Formato de imagen que combina las ventajas del JPEG y el PNG.
  • BMP: Imágenes no comprimidas, de mejor calidad.
  • HEIF: Similar al WEBP.
  • ANPG: Extensión del formato PNG que permite animar imágenes.

Diferentes métodos para agregar imágenes en Flutter

Flutter ofrece varias formas de mostrar imágenes según su origen. Aquí están los métodos disponibles:

  • Image.asset: Para imágenes locales (assets).
  • Image.network: Para imágenes en línea a través de una URL.
  • Image.file: Para imágenes provenientes del almacenamiento local del dispositivo.
  • Image.memory: Para imágenes almacenadas en memoria en forma de bytes.
  • Image.new: Un método flexible que permite cargar imágenes desde varias fuentes.

Uso de Image.asset para imágenes locales

El método Image.asset se utiliza para mostrar imágenes almacenadas localmente en tu proyecto Flutter. Primero, debes colocar la imagen en una carpeta específica de tu proyecto. Se recomienda crear una carpeta assets/images en la raíz de tu proyecto para organizar todas tus imágenes.

Luego, debes declarar esa carpeta en el archivo pubspec.yaml para que Flutter sepa dónde encontrar tus recursos. Agrega la sección assets de la siguiente manera:

flutter:
  assets:
    - assets/images/mi_imagen.png

Finalmente, puedes usar el widget Image.asset para mostrar la imagen en tu aplicación. Asegúrate de proporcionar la ruta relativa (como en pubspec.yaml) y no la ruta completa:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Ejemplo de Image.asset'),
        ),
        body: Center(
          child: Image.asset('assets/images/mi_imagen.png'),
        ),
      ),
    );
  }
}

Uso de Image.network para mostrar imágenes desde una URL

El método Image.network se utiliza para mostrar imágenes obtenidas en línea desde una URL. Aquí tienes un ejemplo sencillo:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Ejemplo de Image.network'),
        ),
        body: Center(
          child: Image.network('https://example.com/mi_imagen.png'),
        ),
      ),
    );
  }
}

Gestión de errores de carga

Al cargar una imagen desde una URL, pueden ocurrir errores (URL incorrecta, falta de conexión). Flutter ofrece soluciones para gestionar estos errores y mejorar la experiencia del usuario:

  • errorBuilder: Permite mostrar un mensaje o una alternativa en caso de fallo de la carga.
  • loadingBuilder: Muestra un indicador mientras se carga la imagen.

Por ejemplo, aquí tienes cómo implementar un loadingBuilder:

Image.network(
  'https://example.com/mi_imagen.png',
  loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
    if (loadingProgress == null) {
      return child;
    } else {
      return Center(
        child: CircularProgressIndicator(
          value: loadingProgress.expectedTotalBytes != null
              ? loadingProgress.cumulativeBytesLoaded / (loadingProgress.expectedTotalBytes ?? 1)
              : null,
        ),
      );
    }
  },
)

También te invito a leer mi artículo sobre el widget Placeholder, que describe más en detalle cómo implementar loadingBuilder.

Y aquí un ejemplo de errorBuilder para mostrar un widget alternativo en caso de error al cargar la imagen:

Image.network(
  'https://example.com/mi_imagen.png',
  errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
    return Center(
      child: Text('Error al cargar'),
    );
  },
)

Gestión de caché de imágenes

Por defecto, Flutter almacena en caché las imágenes cargadas mediante Image.network. Esto significa que las imágenes que ya se han cargado una vez se almacenarán localmente para que puedan reutilizarse sin necesidad de descargarlas nuevamente.

Sin embargo, para un control más avanzado del caché, puedes utilizar paquetes externos como cached_network_image.

Usar Image.file para mostrar imágenes locales

El método Image.file te permite mostrar contenido del sistema de archivos local. Por ejemplo, puedes usar imágenes generadas por el usuario o descargadas.

Para usar este método:

  1. Comienza por importar las bibliotecas darty flutter/material.dart.
  2. Usa el método Image.file() y dale como parámetro un objeto de tipo ‘File’, que apuntará a la imagen local que quieres mostrar.

Ejemplo:

import 'package:flutter/material.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Ejemplo de Image.file'),
        ),
        body: Center(
          child: Image.file(File('/ruta/a/mi_imagen.png')),
        ),
      ),
    );
  }
}

Para acceder a las imágenes almacenadas en el dispositivo, puedes usar packages como image_picker.

Usar Image.new cuando no conoces el tipo de recurso por adelantado

El método Image.new te permite crear instancias basadas en la fuente que le proporciones. La ventaja es que puedes manejar diferentes tipos de contenido con un solo método. Aquí algunos ejemplos:

Image.new(asset: 'assets/images/mi_imagen.png')
Image.new(file: File('/ruta/a/mi_imagen.png'))
Image.new(network: 'https://example.com/mi_imagen.png')
Image.new(memory: Uint8List.fromList([/* datos de la imagen */]))

Consejos para optimizar la visualización de tus imágenes

Para mejorar el rendimiento y la experiencia del usuario en tus aplicaciones Flutter, aquí algunos consejos:

  • Redimensiona tus imágenes para evitar archivos pesados.
  • Usa formatos de imagen optimizados como WEBP para reducir el tamaño del archivo sin perder calidad.
  • Almacena en caché las imágenes para evitar descargas múltiples.
  • Precarga tus imágenes para mejorar los tiempos de carga.

Siguiendo estas buenas prácticas, maximizarás el rendimiento de tu aplicación y garantizarás una experiencia fluida y agradable para los usuarios.

Propiedades y técnicas comunes relacionadas con imágenes en Flutter

El widget Image tiene varias propiedades que te permiten mejorar el diseño de tu contenido. Estas propiedades controlan la opacidad, añaden bordes, ajustan el tamaño, y mucho más. A continuación algunas de las más usadas:

Gestionar la opacidad

Para ajustar la opacidad de una imagen, puedes usar la propiedad color combinada con colorBlendMode. Esto permite aplicar un tinte de color a la imagen con cierto grado de transparencia. Por ejemplo, oscurecer una imagen un 50% aplicando un tinte negro:

Image.asset(
  'assets/images/mi_imagen.png',
  color: Colors.black.withOpacity(0.5), // Aplica opacidad a la imagen
  colorBlendMode: BlendMode.darken, // Mezcla el color con la imagen
)

Agregar un borde

Para agregar un borde alrededor de una imagen, puedes usar el widget Container y encapsular la imagen dentro de él, definiendo la propiedad decoration para crear el borde.

Container(
  decoration: BoxDecoration(
    border: Border.all(color: Colors.blueAccent, width: 5), // Borde azul de 5 píxeles
  ),
  child: Image.asset('assets/images/mi_imagen.png'),
)

Redimensionar una imagen

Para redimensionar una imagen en Flutter, puedes usar las propiedades width y height del widget Image. Esto te permite definir el tamaño exacto de la imagen.

Image.asset(
  'assets/images/mi_imagen.png',
  width: 100, // Ancho establecido en 100 píxeles
  height: 100, // Alto establecido en 100 píxeles
)

Rellenar un contenedor con una imagen

La propiedad fit te permite definir cómo la imagen se ajusta dentro de su contenedor. Puedes usar opciones como BoxFit.cover, BoxFit.contain o BoxFit.fill.

Image.asset(
  'assets/images/mi_imagen.png',
  fit: BoxFit.cover, // La imagen cubrirá todo el espacio disponible
)

La propiedad BoxFit.cover mostrada aquí hace que la imagen llene completamente el espacio, recortándola si es necesario.

Agregar esquinas redondeadas a una imagen

Para agregar esquinas redondeadas a una imagen, puedes usar ClipRRect, un widget que te permite cortar los bordes de la imagen para obtener un efecto redondeado.

ClipRRect(
  borderRadius: BorderRadius.circular(20), // Esquinas redondeadas a 20 píxeles
  child: Image.asset('assets/images/mi_imagen.png'),
)

También puedes aprender más en mi guía sobre cómo hacer una imagen redonda en Flutter.

Aplicar sombra a una imagen

Para agregar una sombra debajo de una imagen, encapsula la imagen en un Container y usa la propiedad BoxShadow en decoration.

Container(
  decoration: BoxDecoration(
    boxShadow: [
      BoxShadow(
        color: Colors.black.withOpacity(0.5), // Color de la sombra
        spreadRadius: 5, // Expansión de la sombra
        blurRadius: 7, // Radio del desenfoque de la sombra
        offset: Offset(0, 3), // Desplazamiento de la sombra
      ),
    ],
  ),
  child: Image.asset('assets/images/mi_imagen.png'),
)

Conclusión

Ahora eres capaz de agregar imágenes a tu aplicación para mejorar la experiencia del usuario o trabajar con fotos. Tu aplicación está tomando forma, pero ¿cómo agregar botones? Te lo explico en la siguiente guía:

Avatar de Pedro Cortez