C 更改jpeglib中的特定像素

C 更改jpeglib中的特定像素,c,libjpeg,C,Libjpeg,我们提取了变量char*raw_图像中的jpeg图像。 在写入新图片之前,我们如何更改原始数据中的特定像素? 我们正在用c语言编程 这是我们写和读图像的功能: #include <stdio.h> #include "jpeglib.h" #include <stdlib.h> /* we will be using this uninitialized pointer later to store raw, uncompressd image */ unsigned

我们提取了变量char*raw_图像中的jpeg图像。 在写入新图片之前,我们如何更改原始数据中的特定像素? 我们正在用c语言编程

这是我们写和读图像的功能:

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

/* we will be using this uninitialized pointer later to store raw, uncompressd image */
unsigned char *raw_image = NULL;
unsigned char *raw_image_tmp = NULL;

/* dimensions of the image we want to write */
int width = 0;
int height = 0;
int bytes_per_pixel = 3;   /* or 1 for GRACYSCALE images */
int color_space = JCS_RGB; /* or JCS_GRAYSCALE for grayscale images */ 

/**
 * read_jpeg_file Reads from a jpeg file on disk specified by filename and saves into the 
 * raw_image buffer in an uncompressed format.
* 
* \returns positive integer if successful, -1 otherwise
* \param *filename char string specifying the file name to read from
*
*/

int read_jpeg_file( char *filename )
{
/* these are standard libjpeg structures for reading(decompression) */
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
/* libjpeg data structure for storing one row, that is, scanline of an image */
JSAMPROW row_pointer[1];

FILE *infile = fopen( filename, "rb" );
unsigned long location = 0;
int i = 0;

if ( !infile )
{
    printf("Error opening jpeg file %s\n!", filename );
    return -1;
}
/* here we set up the standard libjpeg error handler */
cinfo.err = jpeg_std_error( &jerr );
/* setup decompression process and source, then read JPEG header */
jpeg_create_decompress( &cinfo );
/* this makes the library read from infile */
jpeg_stdio_src( &cinfo, infile );
/* reading the image header which contains image information */
jpeg_read_header( &cinfo, TRUE );
/* Uncomment the following to output image information, if needed. */
/*--
printf( "JPEG File Information: \n" );
printf( "Image width and height: %d pixels and %d pixels.\n", cinfo.image_width, cinfo.image_height );
printf( "Color components per pixel: %d.\n", cinfo.num_components );
printf( "Color space: %d.\n", cinfo.jpeg_color_space );
--*/
width = cinfo.image_width;
height = cinfo.image_height; 

/* Start decompression jpeg here */
jpeg_start_decompress( &cinfo );

/* allocate memory to hold the uncompressed image */
raw_image = (unsigned char*)malloc( cinfo.output_width*cinfo.output_height*cinfo.num_components );
/* now actually read the jpeg into the raw buffer */
row_pointer[0] = (unsigned char *)malloc( cinfo.output_width*cinfo.num_components );
/* read one scan line at a time */
while( cinfo.output_scanline < cinfo.image_height )
{
    jpeg_read_scanlines( &cinfo, row_pointer, 1 );
    for( i=0; i<cinfo.image_width*cinfo.num_components;i++) 
        raw_image[location++] = row_pointer[0][i];
}
/* wrap up decompression, destroy objects, free pointers and close open files */
jpeg_finish_decompress( &cinfo );
jpeg_destroy_decompress( &cinfo );
free( row_pointer[0] );
fclose( infile );
/* yup, we succeeded! */
return 1;
}

/**
 * write_jpeg_file Writes the raw image data stored in the raw_image buffer
 * to a jpeg image with default compression and smoothing options in the file
 * specified by *filename.
 *
 * \returns positive integer if successful, -1 otherwise
 * \param *filename char string specifying the file name to save to
 *
 */
int write_jpeg_file( char *filename )
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;

/* this is a pointer to one row of image data */
JSAMPROW row_pointer[1];
FILE *outfile = fopen( filename, "wb" );

if ( !outfile )
{
    printf("Error opening output jpeg file %s\n!", filename );
    return -1;
}
cinfo.err = jpeg_std_error( &jerr );
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);

/* Setting the parameters of the output file here */
cinfo.image_width = width;  
cinfo.image_height = height;
cinfo.input_components = bytes_per_pixel;
cinfo.in_color_space = color_space;
/* default compression parameters, we shouldn't be worried about these */
jpeg_set_defaults( &cinfo );
/* Now do the compression .. */
jpeg_start_compress( &cinfo, TRUE );
/* like reading a file, this time write one row at a time */

while( cinfo.next_scanline < cinfo.image_height)
{
    cinfo.image_width = width;
    row_pointer[0] = &raw_image[ cinfo.next_scanline * cinfo.image_width *  cinfo.input_components];
    jpeg_write_scanlines( &cinfo, row_pointer, 1 );

}
/* similar to read file, clean up after we're done compressing */
jpeg_finish_compress( &cinfo );
jpeg_destroy_compress( &cinfo );
fclose( outfile );
/* success code is 1! */
return 1;
}
#包括
#包括“jpeglib.h”
#包括
/*稍后我们将使用这个未初始化的指针来存储原始的、未压缩的图像*/
无符号字符*原始图像=空;
无符号字符*raw_image_tmp=NULL;
/*我们想要写的图像的尺寸*/
整数宽度=0;
整数高度=0;
每像素整数字节=3;/*或1用于灰度图像*/
int color_space=JCS_RGB;/*或用于灰度图像的JCS_灰度*/
/**
*read_jpeg_文件从文件名指定的磁盘上的jpeg文件中读取并保存到
*未压缩格式的原始图像缓冲区。
* 
*\如果成功,则返回正整数,否则返回-1
*\param*filename指定要从中读取的文件名的字符字符串
*
*/
int read_jpeg_文件(字符*文件名)
{
/*这些是用于读取(解压缩)的标准libjpeg结构*/
结构jpeg\u解压缩\u结构cinfo;
结构jpeg\u错误\u管理器jerr;
/*libjpeg数据结构,用于存储一行,即图像的扫描线*/
JSAMPROW行_指针[1];
文件*infile=fopen(文件名,“rb”);
无符号长位置=0;
int i=0;
如果(!infle)
{
printf(“打开jpeg文件%s\n!时出错,文件名”);
返回-1;
}
/*这里我们设置了标准的libjpeg错误处理程序*/
cinfo.err=jpeg\u std\u error(&jerr);
/*设置解压缩过程和源代码,然后读取JPEG标题*/
jpeg\u创建\u解压缩(&cinfo);
/*这使库从infle读取*/
jpeg_stdio_src(&cinfo,infle);
/*读取包含图像信息的图像标题*/
jpeg_read_头(&cinfo,TRUE);
/*如果需要,请取消注释以下内容以输出图像信息*/
/*--
printf(“JPEG文件信息:\n”);
printf(“图像宽度和高度:%d像素和%d像素。\n”,cinfo.Image\u宽度,cinfo.Image\u高度);
printf(“每像素的颜色分量:%d.\n”,cinfo.num\u分量);
printf(“颜色空间:%d.\n”,cinfo.jpeg\u颜色空间);
--*/
宽度=cinfo.image\u宽度;
高度=cinfo.image\u高度;
/*从这里开始解压缩jpeg*/
jpeg\u开始\u解压缩(&cinfo);
/*分配内存以保存未压缩的图像*/
原始图像=(无符号字符*)malloc(cinfo.output\u width*cinfo.output\u height*cinfo.num\u组件);
/*现在将jpeg读入原始缓冲区*/
行指针[0]=(无符号字符*)malloc(cinfo.output\u width*cinfo.num\u组件);
/*一次读取一个扫描行*/
while(cinfo.output\u扫描线for(i=0;iraw_image是指向大小为imagewidth*imageheight*3的字符数组的指针。“3”表示RGB三元组中的三个组件

查看代码,我理解的是,jpeg图像被采集并读入缓冲区,然后被发送到解压图像的处理器。此外,解压后的像素数据被写入原始图像缓冲区。下面的代码通过逐行写入来完成这项工作。因此,条件“cinfo.output\u scanlinewhile(cinfo.output\u扫描线对于(i=0;我已尝试插入代码
for(i=0;i
但它不起作用-什么都没有发生。我确信整个原始图像现在都充满了值33U。但是你必须把它写在某个地方来查看更改。在return 1语句上方,请包含这段代码,{file of p;of p=fopen(“out.raw”,wb);fwrite(raw_image,sizeof(char),cinfo.image_widthcinfo.image_height*3,of p);fclose(of p);}。尝试用irfan视图打开“out.raw”文件。您肯定可以看到所做的更改。如果您发现了什么,请解释
while( cinfo.output_scanline < cinfo.image_height )
{
    jpeg_read_scanlines( &cinfo, row_pointer, 1 );
    for( i=0; i<cinfo.image_width*cinfo.num_components;i++) 
        raw_image[location++] = row_pointer[0][i];
}
for (i=0; i < cinfo.image_height; i++){
 for (j=0; j < cinfo.image_width; j++){
   // Pixel (i,j)
   raw_image[(i*cinfo.image_width*3)+(j*3)+0]; // Red Pixel
   raw_image[(i*cinfo.image_width*3)+(j*3)+1]; // Green Pixel
   raw_image[(i*cinfo.image_width*3)+(j*3)+2]; // Blue Pixel
   // Now you have pixel (i,j). You can do any thing with this.
 }
}