Manipulação de imagens no formato PPM

O artigo seguinte faz uma introdução sobre o formato ".ppm", que faz o armazenamento de forma simples e "bruta" de imagens. Além de como manipular o arquivo, para podermos aplicar filtros de imagem já existentes ou criar nossos próprios filtros.

[ Hits: 32.194 ]

Por: Pablo Margreff em 16/01/2015 | Blog: https://pmargreff.wordpress.com/


Abrindo e salvando arquivo ppm



Primeiro precisamos exportar as imagens para o formato ppm, faremos isso utilizando o Gimp. Abra a imagem, e após isso vá na aba Arquivo, clique em exportar como e depois disso selecione o formato .ppm e altere o final do nome do arquivo de .*formato para .ppm, selecione modo ASCII. Após isso cole o arquivo gerado.

Arquivo > Exportar como > selecionar formato .ppm e alterar nome do arquivo para .ppm > ASCII

Note que o arquivo gerado pesa muito mais do que a imagem original, mesmo a imagem sendo pequena provavelmente ela vá ocupar alguns MBytes, isso por causa da redundância de informação já comentada antes.

Antes de partir para a parte da programação, abra o arquivo em um editor de texto simples de sua preferência e apague a linha que se inicia pela #, ou seja, o comentário.

Main:

#include 
#include 
#define MAX 500

typedef struct {
    int r, g, b;
} pixel;


int main(int argc, char** argv) {
    pixel imagem[MAX][MAX]; //cria uma matriz de pixeis para armazenar a imagem
    char code[3]; //o código para saber se a imagem é ascii ou binária
    int max; //o valor máximo de tonalidade de cada pixel
    int larg, alt; // largura e altura da imagem em pixeis

    
    return 0;
}

A função main contém a criação das variáveis e da matriz imagens. A matriz imagem é composta pelo tipo pixel, que por sua vez abriga em sua estrutura três inteiros, r, g, b, cada um contendo um tom, como foi anteriormente mencionado. Fora isso, ela tem apenas as chamadas de funções, que serão explicadas a seguir.

A função ler_ascii faz a leitura do arquivo quando está no formato ascii.

void ler_ascii(pixel imagem[MAX][MAX], char *code, int *max, int *coluna, int *linha) {
    int i, j;
    FILE *arquivo;

    char nome_arq[50];
    printf("entre com o nome do arquivo\n");
    scanf("%s", nome_arq);

    if ((arquivo = fopen(nome_arq, "r")) == NULL) {
        printf("Erro ao abrir o arquivo %s\n", nome_arq);
        exit(1);
    }

    fscanf(arquivo, "%s", code);
    fscanf(arquivo, "%d", coluna);
    fscanf(arquivo, "%d", linha);
    fscanf(arquivo, "%d", max);

    for (i = 0; i < *linha; i++) {
        for (j = 0; j < *coluna; j++) {
            fscanf(arquivo, "%d", &imagem[i][j].r);
            fscanf(arquivo, "%d", &imagem[i][j].g);
            fscanf(arquivo, "%d", &imagem[i][j].b);
        }
    }

    fclose(arquivo);
}

O funcionamento dela é simples de entender, primeiro pega o código da imagem, depois as dimensões e por fim o valor máximo, após isso entra em um loop que percorre a matriz salvando cada tom de cada pixel na estrutura imagem.

A função salvar_ascii salva o arquivo no padrão ascii.

void salvar_ascii(pixel imagem[MAX][MAX], char *code, int max, int coluna, int linha) {
    int i, j;
    FILE *arquivo;

    char nome_arq[50];
    printf("entre com o nome que deseja salvar: \n");
    scanf("%s", nome_arq);

    arquivo = fopen(nome_arq, "w");

    fprintf (arquivo, "P3\n");
    fprintf (arquivo, "%d\n ", coluna);
    fprintf (arquivo, "%d\n", linha);
    fprintf (arquivo, "%d\n", max);

    for (i = 0; i < linha; i++) {
        for (j = 0; j < coluna; j++) {
            fprintf(arquivo, "%d ", imagem[i][j].r);
            fprintf(arquivo, "%d ", imagem[i][j].g);
            fprintf(arquivo, "%d\n", imagem[i][j].b);
        }
    }

    fclose(arquivo);
}

Parecida com a anterior, as diferenças estão na passagem dos valores que é feita por parâmetro e não por referência já que as mesmas não serão alteradas. Outra coisa diferente é que o "code" da imagem já é salvo como P3, e não pega o char code, pois isso evita o erro ao salvarmos uma imagem de um arquivo aberto que estava em binário.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução ao formato ppm e seus usos
   2. Abrindo e salvando arquivo ppm
   3. Filtros
Outros artigos deste autor

Aumentando sua produtividade com o teclado padrão Dvorak

Algoritmos de compressão

Gerando Números Aleatórios

Leitura recomendada

DoTheWorld - Biblioteca completa para manipulação de Arquivos e Pastas em C

Manipulação de arquivos em C++

Manipulando arquivos em C (parte 1)

Manipulando arquivos em C (parte 2)

A mágica do polimorfismo e seus conceitos na ótica de C/C++

  
Comentários
[1] Comentário enviado por fabio em 16/01/2015 - 09:58h

Muito bom artigo, meus parabéns! Nunca havia lido nada que abordasse tal assunto.

[2] Comentário enviado por Nerdiarretado em 08/05/2019 - 11:31h

Ótimo artigo! Parabéns pela iniciativa, estou também desenvolvendo um mesmo programa e esse será uma ótima referência!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts