【发布时间】:2015-11-27 08:38:00
【问题描述】:
我正在尝试将 JPEG 从 RGB 转换为 HSL。我做了一个读取和写入函数来打开文件(我使用 libjpeg 函数)并从这张图片的 HSL 值(色相、饱和度、亮度)中绘制 ASCII 所以我找到了一个将 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;
}
}
法语中的 cmets 对不起,因为它是针对大学的,我的老师希望我们评论我们的程序(正常)
谢谢你们的帮助。
【问题讨论】:
-
我不确定,但几年前我做过类似的事情。您可以访问图像的未压缩值吗?如果是,理论上您应该能够遍历它们并应用转换。为简化起见,您可以从单色图像开始,然后只打印缓冲区的内容。