Introdução
Um pequeno ateliê de impressão precisa de um cartão-postal feito de uma grade de cores. Você primeiro executará uma amostra completa de quatro por quatro, dará a ela uma tinta mais quente e depois concluirá um programa C que transforma um padrão retangular de caracteres em um arquivo de imagem real.
Você precisa conhecer variáveis, condições, laços, arrays e funções de C, além de navegação básica no terminal. A indexação bidimensional e a saída de imagens são explicadas aqui. O ambiente preparado no navegador inclui o terminal Workspace e o Postcard Preview. A imagem é um arquivo P3 PPM: números legíveis, não um PNG. O tempo de leitura e prática é uma estimativa do autor, não uma medição do tempo de conclusão de iniciantes.
Imprima e mude a cor de uma pequena amostra
Nesta etapa, você verá uma amostra C completa se transformar em uma imagem e depois mudará uma cor de tinta.
Abra a aba Workspace. Seu terminal está em /home/labex/project/postcards; o cd explícito também permite voltar depois de trocar de diretório. pwd mostra o diretório atual e ls lista seus arquivos.
cd /home/labex/project/postcards
pwd
ls
Os arquivos preparados são sample.c, o programa incompleto card.c e o arquivo fornecido art.h. Altere apenas sample.c e card.c; mantenha art.h intacto. cat mostra um arquivo sem editá-lo:
cat sample.c
A amostra usa uma grade de quatro linhas e quatro colunas. Em grid[row][col], o primeiro índice escolhe uma linha de cima para baixo e o segundo uma coluna da esquerda para a direita. Ambos começam em zero. Cada elemento vale 0 ou 1 e seleciona uma tripla RGB em color. RGB significa vermelho, verde e azul; cada componente é um inteiro de 0 a 255. O segundo índice de color[c][0] seleciona vermelho, [1] verde e [2] azul.
printf escreve texto na saída padrão, normalmente este terminal. \n inicia uma nova linha. Os arquivos P3 começam com P3, largura e altura e, depois, o valor máximo dos componentes, 255. Em seguida vêm as triplas RGB, lidas da esquerda para a direita em cada linha, da linha superior para a inferior. Espaços em branco separam os números, portanto uma tripla RGB por linha é válida. P3 também permite comentários com #.
Compile a amostra. gcc é o compilador C; -std=c11 seleciona C11, -Wall -Wextra ativa avisos úteis e -o sample dá ao executável o nome sample.
gcc -std=c11 -Wall -Wextra sample.c -o sample
./sample executa o arquivo deste diretório. > redireciona a saída padrão para um arquivo em vez do terminal. O shell abre ou substitui esse arquivo antes de executar o programa. Use o novo nome mostrado:
./sample > sample.ppm
Mude para a aba Postcard Preview. Clique em Refresh files, selecione sample.ppm em Postcard file e clique em Open postcard. O status mostra 4 × 4 pixels · sample.ppm. Você deverá ver uma marca escura assimétrica sobre um fundo creme. A visualização mostra o arquivo que você acabou de criar; ela não completa pixels ausentes.
Volte para Workspace. Troque a tinta escura de {30, 76, 64} pela cor quente {170, 70, 45}. O comando de edição sed abaixo usa s/old/new/ para substituir exatamente esse texto, e -i salva a alteração em sample.c. As aspas simples passam a substituição para sed como um único argumento sem modificações.
sed -i 's/{30, 76, 64}/{170, 70, 45}/' sample.c
Recompile após editar o código-fonte: o executável antigo não se atualiza sozinho.
gcc -std=c11 -Wall -Wextra sample.c -o sample
./sample > sample.ppm
Mude para Postcard Preview, mantenha sample.ppm selecionado e clique novamente em Open postcard. Apenas a cor do primeiro plano deve mudar; as dimensões e os pixels creme devem permanecer iguais.
Se o terminal informar que um arquivo não foi encontrado, volte ao espaço de trabalho usando cd e ls, já ensinados. Se a visualização disser que o arquivo não existe, volte para Workspace e confirme que a compilação terminou com sucesso antes de executar ./sample > sample.ppm. Um erro do compilador significa que nenhum novo executável foi criado: corrija a linha indicada no código e compile novamente.
Associe um padrão retangular a pixels RGB
Nesta etapa, você concluirá o gerador de cartões e abrirá sua saída real.
Comece em Workspace, em /home/labex/project/postcards. Leia a arte fornecida e o gerador incompleto:
cd /home/labex/project/postcards
cat art.h
cat card.c
#include "art.h" disponibiliza essas definições preparadas durante a compilação de card.c. #define WIDTH 5 e #define HEIGHT 3 dão nomes às dimensões. pattern tem três linhas de cinco caracteres numéricos. Cada linha de string reserva WIDTH + 1 caracteres porque C guarda um terminador de valor zero após os caracteres visíveis; os laços usam apenas as cinco posições visíveis.
A primeira linha, "10000", começa com a cor 1 da paleta, seguida de quatro pixels de cor 0. O caractere '2' não é o inteiro 2. Subtrair o caractere '0' converte um dos caracteres numéricos fornecidos em seu índice na paleta: '2' - '0' vale 2. A arte contém apenas dígitos de 0 a 3, correspondentes às quatro linhas da paleta. Preserve o padrão, as dimensões e as cores. Use WIDTH e HEIGHT nos laços para que a recompilação também funcione com padrões retangulares fornecidos de 1 a 16 colunas e linhas, usando os mesmos índices de paleta de 0 a 3.
O gerador incompleto escreve um cabeçalho, mas nenhum pixel. Só o cabeçalho de um arquivo não é uma imagem. Complete-o com um laço externo sobre y (linhas) e um interno sobre x (colunas). pattern[y][x] escolhe o caractere; palette[c][0..2] escolhe seus valores RGB. Os marcadores %d de printf imprimem os argumentos inteiros na ordem indicada.
Use o código-fonte completo abaixo. cat > card.c substitui esse arquivo. <<'EOF' inicia um here-document: o shell copia literalmente as linhas seguintes até encontrar uma linha contendo apenas EOF. As aspas no delimitador impedem expansões do shell no código C. Copie o bloco inteiro, incluindo o último 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
Compile e gere um novo arquivo de saída:
gcc -std=c11 -Wall -Wextra card.c -o card
./card > original.ppm
A ferramenta de inspeção fornecida apenas decodifica um arquivo; não pode gerar nem reparar seu cartão. Execute-a com o nome do arquivo como argumento:
python3 /home/labex/.local/share/pixel-postcards/inspect.py original.ppm
Saída esperada:
5 x 3 pixels; 15 RGB triples; max value 255
Por que esses números são úteis? Um quadrado poderia esconder a troca das dimensões. Este padrão de cinco colunas e três linhas deve ser mais largo do que alto, com uma faixa escura à esquerda. WIDTH controla o laço interno e HEIGHT o externo; trocá-los pode acessar posições fora de uma linha ou deixar pixels de fora.
Mude para Postcard Preview. Clique em Refresh files, selecione original.ppm e depois Open postcard. Confira o status 5 × 3 e compare as linhas com art.h. Clique em Download PPM para salvar o arquivo de imagem real. O navegador pode baixar PPM em vez de mostrá-lo diretamente; use esta visualização para vê-lo. Volte para Workspace para a verificação do laboratório.
A captura mostra original.ppm selecionado, suas dimensões salvas de 5 × 3 e Download PPM abaixo da imagem. Compare a faixa escura da esquerda e todas as três linhas.
![]()
Mantenha card.c, o executável card, art.h e original.ppm neste espaço de trabalho.
Se a visualização informar um erro na quantidade de pixels, o arquivo existe, mas seu conteúdo está incompleto: confira os limites dos dois laços, salve card.c, recompile e gere original.ppm novamente. A ampliação na tela não altera as dimensões salvas. No próximo laboratório você criará arquivos de imagem realmente ampliados.
Resumo
Você compilou e mudou as cores de uma pequena amostra e depois associou um array retangular de caracteres a triplas RGB. Seu programa C criou um arquivo P3 real, que você decodificou, visualizou e baixou. Você praticou a indexação com a linha primeiro e o redirecionamento da saída padrão.


