Преобразование JPEG из RGB в HSL на C

Я пытаюсь преобразовать JPEG из RGB в HSL. Я сделал функцию чтения и записи для открытия файла (я использую функции libjpeg) и рисования ASCII из этого рисунка из его значений HSL (оттенок, насыщенность, яркость), поэтому я нашел псевдокод для преобразования RGB в HSL: http://pastebin.com/2sf1b25L, и я преобразовал его в C. Мой вопрос: как теперь преобразовать каждый пиксель один за другим от RGB до HSL? будет ли это работать, если я использую эту функцию RGB_to_HSL в моей «записи» и применяю ее к каждому блоку буферного массива?

main.c:

#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include "fonctions.h"


int main (int argc, char** argv){


    int H;
    int W;
    int C;
    FILE *fichier = NULL; //file pour l'image entrée
    FILE *image = NULL; //file pou l'image à la sortie
    unsigned char **buffer; //buffer où sera contenue l'image

    buffer = malloc(256*(sizeof(unsigned char*)));

    if (argv[1] == NULL)
        fichier = fopen("cara.jpg", "r");
    else
        fichier = fopen(argv[1], "r");
    image = fopen("cara_image_cree.jpg", "wb");

    if (fichier == NULL)
        printf("Probleme lecture");

    printf("Cara Delevingne\n");
    buffer = lire(fichier, &H, &W, &C);
    ecrire(&H, &W, &C, buffer, image);

    fclose(fichier);
    fclose(image);
    return 0;
}   

read.c:

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <jpeglib.h>
#include <jerror.h>

unsigned char** lire (FILE* file, int *H, int *W, int *C){

struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;

int n = 0;
unsigned char** buffer; // buffer qui va contenir l'image

/*printf("SHITSHITSHITSHITDEBUG\n");
fflush(stdout);*/
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo); // Initialisation de la structure

jpeg_stdio_src(&cinfo,file);  // file est de type FILE * (descripteur de fichier
                              // sur le fichier jpega decompresser)
jpeg_read_header(&cinfo,TRUE);// lecture des infos sur l'image jpeg


jpeg_start_decompress(&cinfo);// lancement du processus de decompression


*H = cinfo.output_height; // on récupère la hauteur
*W = cinfo.output_width; // on récupère la largeur
*C = cinfo.output_components; // on regarde si l'image est en couleurs ou N&B


buffer=malloc( (*H) *sizeof(unsigned char*) ); // on alloue de la mémoire au buffer selon le nb de lignes de pixels qu'il va devoir prendre

while (n < *H) // tant que le compteur n'a pas dépassé l'image
 {
    buffer[n] = (unsigned char*) malloc( (*W) * (*C) *sizeof(unsigned char *) ); // on alloue à chaque ligne, la taille de la largeur

     jpeg_read_scanlines(&cinfo,buffer+n,1); // lecture des n lignes suivantes de l'image
                                          // dans le buffer (de type unsigned char *)
     n++;
}

jpeg_finish_decompress(&cinfo);

jpeg_destroy_decompress(&cinfo);

return buffer;
}

write.c

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <jpeglib.h>
#include <jerror.h>

void ecrire (int *H, int *W, int *C, unsigned char **buffer, FILE *file){

struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;

int n = 0;

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo); // Initialisation de la structure

jpeg_stdio_dest(&cinfo,file);  // file est de type FILE * (descripteur de fichier
                              // sur le fichier jpeg compressé final)
cinfo.image_width= *W;          // nombre de ligne de l'image
cinfo.image_height= *H;         // nombre de pixel par ligne
cinfo.input_components = *C;      // 3 pour une image couleur, 1 pour une N&B
cinfo.in_color_space= JCS_RGB;
                              // JCS_GRAYSCALE pour une image N&B
jpeg_set_defaults(&cinfo);    // initialisation des paramètres de compression
jpeg_start_compress(&cinfo,TRUE); // lancement du processus de decompression


while (n < *H)
{
    jpeg_write_scanlines(&cinfo,buffer+n,1); // écriture des n lignes suivantes de l'image
                                          // stockées dans le buffer (de type unsigned char *)
     n++;
}

jpeg_finish_compress(&cinfo);

jpeg_destroy_compress(&cinfo);

}

RGB_to_HSL.c (нигде пока не пользовался! Не знаю где использовать):

void rgbToHsl(int r, int g, int b, int *h, int *s, int *l){
    r/=255; g /= 255; b/=255;
    int max = maximum(r, g, b);
    int min = minimum(r, g, b);
    *l = (max + min)/2;

    if (max == min) 
        *h = *s = 0; // achromatique
    else{
        int d = max - min;
        *s = *l > 0.5 ? d / (2 - max - min) : d / (max + min);
        if (max == r)
            *h = (g-b) / d + (g < b ? 6 : 0);
        if (max == g)
            *h = (b-r) / d + 2;
        if (max == b)
            *h = (r-g) / d + 4;

            /*case r: *h = r;
            case g: *h = g;
            case b: *h = b; */
        }
        *h /= 6;





    }

int maximum (int a, int b, int c){
    if (a > b){
        if (a > c)
            return a;
        else
            return c;
    }
    else{
        if (b > c)
            return b;
        if (c > b)
            return c;
    }
}

int minimum (int a, int b, int c){
    if (a < b){
        if (a < c)
            return a;
        else
            return c;
    }
    else{
        if (b < c)
            return b;
        if (c < b)
            return c;
    }


}

извините за комментарии на французском, это потому, что это для колледжа, и мой учитель хочет, чтобы мы комментировали наши программы (нормально)

Спасибо, ребята, за вашу помощь.


person Henley n    schedule 27.11.2015    source источник
comment
Я не уверен, но я сделал нечто подобное несколько лет назад. Можете ли вы получить доступ к несжатым значениям изображения? Если да, теоретически вы сможете перебрать их и применить преобразование. Для упрощения вы можете начать с монохромного изображения и просто распечатать содержимое буфера.   -  person arc_lupus    schedule 27.11.2015


Ответы (1)


Я не специалист во всем, но похоже, что после декомпрессии у вас есть массив строк развертки в buffer, где buffer[i] является i-й строкой развертки (отсчитывается от нуля). Строки сканирования содержат отдельные пиксели.

Поскольку каждый пиксель преобразуется независимо от других пикселей в вашем алгоритме, теперь вы просто конвертируете пиксели в HSL: цикл по строкам развертки, цикл по пикселям строки развертки, преобразование каждого, возвращение пикселей в строку развертки.

После этого вы можете записать изображение обратно. Я не знаю, нужно ли вам устанавливать разные параметры сжатия для сжатия HSL или сжатия RGB.

person Paul Ogilvie    schedule 27.11.2015