Convierte una cuadrícula en una imagen a color

CBeginner
Practicar Ahora

Introducción

Un pequeño taller de impresión necesita una postal hecha con una cuadrícula de colores. Primero ejecutarás una muestra completa de cuatro por cuatro, le darás una tinta más cálida y después completarás un programa C que convierte un patrón rectangular de caracteres en un archivo de imagen real.

Necesitas conocer variables, condiciones, bucles, arrays y funciones de C, además de navegación básica por el terminal. Aquí se explican la indexación bidimensional y la salida de imágenes. El entorno del navegador incluye el terminal Workspace y Postcard Preview. La imagen es un archivo P3 PPM: números legibles, no un PNG. El tiempo de lectura y práctica es una estimación del autor, no una medición de principiantes.

Imprime y cambia el color de una muestra pequeña

En este paso verás cómo una muestra completa en C se convierte en una imagen y cambiarás una tinta.

Abre la pestaña Workspace. Su terminal está en /home/labex/project/postcards; el cd explícito también permite volver después de cambiar de directorio. pwd muestra el directorio actual y ls enumera sus archivos.

cd /home/labex/project/postcards
pwd
ls

Los archivos preparados son sample.c, el programa incompleto card.c y el archivo proporcionado art.h. Cambia únicamente sample.c y card.c; conserva art.h intacto. cat muestra un archivo sin editarlo:

cat sample.c

La muestra utiliza una cuadrícula de cuatro filas y cuatro columnas. En grid[row][col], el primer índice elige una fila de arriba abajo y el segundo una columna de izquierda a derecha. Ambos empiezan en cero. Cada elemento vale 0 o 1 y selecciona una terna RGB de color. RGB significa rojo, verde y azul; cada componente es un entero entre 0 y 255. El segundo índice de color[c][0] selecciona el rojo, [1] el verde y [2] el azul.

printf escribe texto en la salida estándar, normalmente este terminal. \n inicia una línea nueva. Los archivos P3 comienzan con P3, la anchura y la altura, y después el valor máximo de los componentes, 255. A continuación aparecen las ternas RGB: se leen de izquierda a derecha en cada fila y de la fila superior a la inferior. Los espacios en blanco separan los números, por lo que escribir una terna por línea es válido. P3 también admite comentarios con #.

Compila la muestra. gcc es el compilador C; -std=c11 selecciona C11, -Wall -Wextra activa advertencias útiles y -o sample da al ejecutable el nombre sample.

gcc -std=c11 -Wall -Wextra sample.c -o sample

./sample ejecuta el archivo de este directorio. > redirige la salida estándar a un archivo en lugar de mostrarla en el terminal. El shell abre o reemplaza ese archivo antes de ejecutar el programa. Usa el nuevo nombre que se muestra:

./sample > sample.ppm

Cambia a la pestaña Postcard Preview. Pulsa Refresh files, elige sample.ppm en Postcard file y pulsa Open postcard. El estado indica 4 × 4 pixels · sample.ppm. Verás una marca oscura asimétrica sobre un fondo crema. El visor muestra el archivo que acabas de crear; no completa los píxeles que falten.

Vuelve a Workspace. Cambia la tinta oscura de {30, 76, 64} al color cálido {170, 70, 45}. El comando de edición sed usa s/old/new/ para sustituir ese texto exacto, y -i guarda el cambio en sample.c. Las comillas simples pasan la sustitución a sed como un único argumento sin modificar.

sed -i 's/{30, 76, 64}/{170, 70, 45}/' sample.c

Recompila después de editar el código fuente: el ejecutable anterior no se actualiza por sí solo.

gcc -std=c11 -Wall -Wextra sample.c -o sample
./sample > sample.ppm

Cambia a Postcard Preview, deja seleccionado sample.ppm y pulsa de nuevo Open postcard. Solo debe cambiar el color del primer plano; las dimensiones y los píxeles crema deben seguir iguales.

Si el terminal no encuentra un archivo, vuelve al espacio de trabajo con los comandos cd y ls ya enseñados. Si el visor dice que el archivo no existe, vuelve a Workspace y confirma que la compilación terminó correctamente antes de ejecutar ./sample > sample.ppm. Un error del compilador significa que no se creó un ejecutable nuevo: corrige la línea indicada y vuelve a compilar.

Relaciona un patrón rectangular con píxeles RGB

En este paso completarás el generador de postales y abrirás su resultado real.

Empieza en Workspace, en /home/labex/project/postcards. Lee el dibujo proporcionado y el generador incompleto:

cd /home/labex/project/postcards
cat art.h
cat card.c

#include "art.h" incorpora estas definiciones preparadas al compilar card.c. #define WIDTH 5 y #define HEIGHT 3 dan nombre a las dimensiones. pattern tiene tres filas de cinco caracteres numéricos. Cada cadena reserva WIDTH + 1 caracteres porque C almacena un terminador de valor cero después de los caracteres visibles; los bucles solo utilizan las cinco posiciones visibles.

La primera fila, "10000", empieza con el color 1 de la paleta y continúa con cuatro píxeles de color 0. El carácter '2' no es el entero 2. Restar el carácter '0' convierte uno de los caracteres numéricos proporcionados en su índice de paleta: '2' - '0' vale 2. El dibujo solo contiene dígitos del 0 al 3, correspondientes a las cuatro filas de la paleta. Conserva su patrón, dimensiones y colores. Usa WIDTH y HEIGHT en los bucles para que la recompilación también funcione con patrones rectangulares proporcionados de entre 1 y 16 columnas y filas, con los mismos índices de paleta del 0 al 3.

El generador incompleto escribe una cabecera, pero ningún píxel. Una cabecera no basta para crear una imagen. Complétalo con un bucle exterior sobre y (filas) y otro interior sobre x (columnas). pattern[y][x] elige el carácter; palette[c][0..2] elige sus valores RGB. Los marcadores %d de printf imprimen los argumentos enteros en el orden indicado.

Usa el siguiente código completo. cat > card.c reemplaza ese archivo. <<'EOF' inicia un here-document: el shell copia literalmente las líneas siguientes hasta encontrar una línea que solo contiene EOF. Las comillas del delimitador impiden que el shell expanda el código C. Copia todo el bloque, incluida la última línea EOF.

cat > card.c <<'EOF'
#include <stdio.h>
#include "art.h"

int main(void) {
    printf("P3\n%d %d\n255\n", WIDTH, HEIGHT);
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            int c = pattern[y][x] - '0';
            printf("%d %d %d\n", palette[c][0], palette[c][1], palette[c][2]);
        }
    }
    return 0;
}
EOF

Compila y genera un nuevo archivo de salida:

gcc -std=c11 -Wall -Wextra card.c -o card
./card > original.ppm

La herramienta de inspección proporcionada solo decodifica un archivo; no puede generar ni reparar la postal. Ejecútala pasando el nombre del archivo como argumento:

python3 /home/labex/.local/share/pixel-postcards/inspect.py original.ppm

Salida esperada:

5 x 3 pixels; 15 RGB triples; max value 255

¿Por qué son útiles estos números? Una imagen cuadrada podría ocultar un intercambio de dimensiones. Este patrón de cinco columnas y tres filas debe ser más ancho que alto, con la franja oscura a la izquierda. WIDTH controla el bucle interior y HEIGHT el exterior; intercambiarlos puede acceder fuera de una fila o dejar píxeles sin escribir.

Cambia a Postcard Preview. Pulsa Refresh files, elige original.ppm y pulsa Open postcard. Comprueba el estado 5 × 3 y compara las filas con art.h. Pulsa Download PPM para guardar el archivo real. El navegador puede descargar PPM en lugar de mostrarlo directamente; utiliza este visor para verlo. Vuelve a Workspace para la comprobación del laboratorio.

La captura muestra original.ppm seleccionado, sus dimensiones guardadas de 5 × 3 y Download PPM debajo de la imagen. Compara la franja oscura izquierda y las tres filas.

La postal rectangular en Postcard Preview

Conserva card.c, el ejecutable card, art.h y original.ppm en este espacio de trabajo.

Si el visor informa de un número incorrecto de píxeles, el archivo existe pero está incompleto: revisa los límites de ambos bucles, guarda card.c, recompila y vuelve a generar original.ppm. La ampliación en pantalla no modifica las dimensiones guardadas. En el siguiente laboratorio crearás archivos de imagen realmente ampliados.

Resumen

Has compilado y recoloreado una muestra pequeña y después has relacionado un array rectangular de caracteres con ternas RGB. Tu programa C creó un archivo P3 real que decodificaste, visualizaste y descargaste. Practicaste la indexación por fila primero y la redirección de la salida estándar.