🚀 Go to: Image Filter App
Debido a que beforeinstallprompt
no se triggerea en celulares iOS, se debe abrir desde safari y llevar a cabo los siguientes pasos:
- Compartir la página
- Seleccionar
Agregar a inicio
- Acceder a la aplicación desde FilterApp
-
Instalar Rust siguiendo las instrucciones en https://www.rust-lang.org/tools/install
-
Instalar wasm-pack:
cargo install wasm-pack
- Navegar al directorio del proyecto (frontend):
cd pwa
- Instalar las dependencias de Node.js:
npm install
- Desde la carpeta principal, habilitar el comando de ejecución:
chmod +x build.sh
- Construir/compilar el paquete de exportación para las funciones wasm y correr el servidor local:
./build.sh
- Si ya lo compilaste alguna vez y no hay cambios en
lib.rs
, puedes hacer lo siguiente:
chmod +x dev.sh
./dev.sh
El servidor se iniciará y podrás acceder a la aplicación en tu navegador, en el puerto que se indica en la terminal.
El proyecto demuestra la integración entre Rust y TypeScript/React a través de WebAssembly. Aquí se explica cómo funciona, por ejemplo, la función greet
:
-
Declaración en Rust (
lib.rs
):- La función
greet
está definida en el archivoserver/t2-g5-iic3585/src/lib.rs
- Está decorada con
#[wasm_bindgen]
para hacerla accesible desde JavaScript/TypeScript - Recibe un parámetro
name
de tipo&str
y retorna unString
- La función formatea un mensaje de saludo usando el nombre proporcionado
- La función
-
Compilación a WebAssembly:
- Cuando se compila el proyecto Rust (ejecutando
wasm-pack build
dentro de la carpeta server/t2-g5-iic3585),wasm-pack
genera un paquete WebAssembly - Este paquete se encuentra en
server/t2-g5-iic3585/pkg/
- Contiene las definiciones de tipos TypeScript y el código WebAssembly compilado
- Cuando se compila el proyecto Rust (ejecutando
-
Uso en TypeScript/React (
App.tsx
):- La función se importa desde el paquete generado:
import { greet } from '../../server/t2-g5-iic3585/pkg/t2_g5_iic3585'
- Se puede usar directamente en el componente React como una función normal de TypeScript
- En el ejemplo, se llama con el string "wena los chiquillossss" y el resultado se muestra en el DOM
- La función se importa desde el paquete generado:
Este flujo demuestra cómo Rust puede ser usado para implementar lógica que luego se puede consumir de manera segura y eficiente desde una aplicación web moderna.
El proyecto incluye varias funciones de procesamiento de imágenes implementadas en Rust y accesibles a través de WebAssembly. Aquí se explica cómo usar cada una de ellas:
Primero, se importan las funciones necesarias en el componente React:
import {
apply_blur,
apply_grayscale,
apply_invert,
apply_brighten,
apply_flip_horizontal,
apply_flip_vertical
} from '../../server/t2-g5-iic3585/pkg/t2_g5_iic3585';
- Funciones auxiliares
rgba_to_image
: Convierte un arreglo de bytes (Uint8Array) que representa píxeles en formato RGBA en una imagen manipulable, mediante la biblioteca image de Rust.
// Mediante `ImageBuffer` crea un buffer de imagen a partir de los datos y el tamaño de la imagen. Se envuelve el buffer en un objeto `DynamicImage`, que permite manipular la imagen y lo retorna.
fn rgba_to_image(width: u32, height: u32, data: &[u8]) -> DynamicImage {
let img_buffer = ImageBuffer::<Rgba<u8>, _>::from_raw(width, height, data.to_vec())
.expect("Failed to create image buffer");
DynamicImage::ImageRgba8(img_buffer)
}
encode_image_to_vec
: Toma una imagen dinámica (manipulable) y la vectoriza (Vector de bytes), codificándola como png
. Es posible mutarla gracias a la estructura Cursor
del módulo std::io de Rust, que permite tratar un arreglo de bytes como si fuera un archivo.
// Mediante un buffer `Vec<u8>` vacío, almacena la imagen codificada. Escribe información sobre el buffer y lo retorna con los bytes `png` resultantes.
fn encode_image_to_vec(img: DynamicImage) -> Vec<u8> {
let mut buffer = Vec::new();
img.write_to(&mut Cursor::new(&mut buffer), ImageFormat::Png)
.expect("Failed to encode image");
buffer
}
- Aplicar Blur (Desenfoque)
Desenfoca la imagen mediante el método blur
y un valor mayor o igual a 0:
// image_data: Uint8Array - Datos de la imagen en formato de bytes
// sigma: f32 - Intensidad del desenfoque (mayor valor = más desenfoque)
const blurredImage = apply_blur(imageData, 2.0);
- Convertir a Escala de Grises
Convierte la imagen a escala de grises mediante el método grayscale
:
// image_data: Uint8Array - Datos de la imagen en formato de bytes
const grayscaleImage = apply_grayscale(imageData);
- Invertir Colores
Invierte los colores de la imagen mediante el método invert
:
// image_data: Uint8Array - Datos de la imagen en formato de bytes
const invertedImage = apply_invert(imageData);
- Modificar Brillo
Aumenta o disminuye el brillo de la imagen mediante el método brighten
negativo o positivo:
// image_data: Uint8Array - Datos de la imagen en formato de bytes
// sigma: i32 - Intensidad del brillo (mayor valor = más brillo, puede ser negativo)
const invertedImage = apply_brighten(imageData, 2);
- Flip Horizontal
Gira la imagen sobre el eje Y, haciendo un efecto espejo, mediante el método fliph
:
// image_data: Uint8Array - Datos de la imagen en formato de bytes
const invertedImage = apply_flip_horizontal(imageData);
- Flip Vertical
Gira la imagen sobre el eje X, haciendo un efecto "dado vuelta", mediante el método flipv
:
// image_data: Uint8Array - Datos de la imagen en formato de bytes
const invertedImage = apply_flip_vertical(imageData);