Click to See Complete Forum and Search --> : help with jpeglib


sneakpeak101
September 17th, 2005, 12:48 AM
Hi everyone -
I'm having trouble using the jpeglib and compressing a .bmp into .jpeg, i'm still very new to C++ and what i'm looking for is some sample code or pointers that can help me out, i'm compiling my program using the latest version of dev-c++.

Basically, my program gets a picture from my webcam using capFileSaveDIB(ghCapWnd, "c:\\test.bmp");
Now i'm not sure if it matters if it is saved as a .bmp or .dib, or .jpeg.. of even if it matters, I saw a few examples on net using the same line of code I have so i'm assuming it's correct. The image is saved, and I can view it perfectly using windows picture and fax viewer.

Here is the next piece of code that i'm having trouble with.. it does create the jpeg at 1.78kb (previous size was 225kb) , but the picture is completely black.. I think it's because JSAMPLE .. but i'm not sure.
extern JSAMPLE * image_buffer;
int image_height; /* Number of rows in image */
int image_width;

void write_JPEG_file (char *filename, int quality)
{


struct jpeg_compress_struct cinfo;
cinfo.image_height = 320;
cinfo.image_width = 240;
int imagesize = 3*320*240;
JSAMPLE image_buffer[imagesize];
int i;
for(i=0; i<imagesize; i++) {
image_buffer[i] = (JSAMPLE)0;
}
struct jpeg_error_mgr jerr;
FILE * outfile; /* target file */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
cinfo.err = jpeg_std_error(&jerr);

jpeg_create_compress(&cinfo);
if ((outfile = fopen("test.jpeg", "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);

cinfo.image_width = 320;
cinfo.image_height = 240;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
row_stride = image_width * 3;


while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
(void) jpeg_write_scanlines(&cinfo, row_pointer, cinfo.image_height);
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
}

-

write_JPEG_file ("test.jpeg", 100);
I didn't write the code above, I simply found it on a search engine and tried playing with it, seeing how it was the only thing that would compile for me. The image I use to compress it the one created using capFileSaveDIB(); above, I just edit the code to create a .jpeg instead of a .bmp like it is above.

If anyone can help me it would be much appreciated.. i'm willing to learn, if someone can just point me in the right area.. i've tried and tried to figure out what is wrong but I can't seem to fix it and i'm not used to using the jpeglib, any help is appreciated thanks all.

olivthill
September 17th, 2005, 03:30 AM
The picture is black due to the following lines:
for(i=0; i<imagesize; i++) {
image_buffer[ i ] = (JSAMPLE)0;
} "000" (three zeros) is making the RGB (red green blue) value for a black pixel.
If you replace that loop with this one
for(i=0; i<imagesize; ) {
image_buffer[i++] = (JSAMPLE)255;
image_buffer[i++] = (JSAMPLE)0;
image_buffer[i++] = (JSAMPLE)0;
} your picture will be red.

The picture is saved one line at a time. The pixels for one particular line must be stored in "image_buffer"

You have to adapt the loop in order to place the RGB value of each pixel in a line. There are many articles at codeguru about the DIB format. I haven't had the time, so far, to read them myself, (so excuse me if I'm giving you only a little part of the solution) but that's where you will find how you could extract the RGB values of your pixels, and then, all you'll have to do will be to place series of RGB values in image_buffer.

sneakpeak101
September 17th, 2005, 05:01 AM
Thanks for replying olivthill :)
I see now what you're saying, it shouldn't be too hard then retrieving info about each pixel then outputting it, I may be able to take it from here (thinks..) :P

sneakpeak101
September 21st, 2005, 09:18 AM
I'm still having problems compressing a bmp into a jpeg, ive been attempting to get this to work for a while and i can't get past some stuff.. if anyone can provide me with some source (that converts a bmp into jpeg, the more simple the better for me) in c or c++ that compiles with dev-c++ 4.9.9.2, i'd be willing to wire the person money via money order or western union for helping me out, i'm too stressed to try to get this to work atm so ive resort to this.. As i said above, the more simple the code the better, thanks.. pm me if you like for more info

philkr
September 23rd, 2005, 06:01 AM
I have a piece of code which makes a JPEG screen capture. Hopefully you can modify it that it uses your bitmap instead of the screen capture to compress:

int jpegCapture(char* filename, int quality)
{
HBITMAP hBMP;
HWND desktopWnd;
int width;
int height;
RECT rc;
HDC hDC;
HDC hDCmem;
int posx;
int posy;

struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile;
JSAMPLE* scanline;
COLORREF pixel;

// Make capture bitmap
desktopWnd = GetDesktopWindow();
GetWindowRect(desktopWnd, &rc);
width = rc.right - rc.left;
height = rc.bottom - rc.top;
hDC = GetDC(desktopWnd);
hDCmem = CreateCompatibleDC(hDC);
hBMP = CreateCompatibleBitmap(hDC, width, height);
if(hBMP == NULL) return -2;
SelectObject(hDCmem, hBMP);
BitBlt(hDCmem, 0, 0, width, height, hDC, rc.left, rc.top, SRCCOPY);

// Compress to JPEG using hDCmem
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
outfile = fopen(filename, "wb");
if(outfile == NULL) return -1;
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
if (quality < 0) quality = 0;
else if(quality > 100) quality = 100;
jpeg_set_quality(&cinfo, quality, FALSE);
jpeg_start_compress(&cinfo, TRUE);
scanline = new JSAMPLE[width*3];
for(posy = 0; posy < height; posy++)
{
for(posx = 0; posx < width; posx++)
{
pixel = GetPixel(hDCmem, posx, posy);
scanline[posx*3+0] = GetRValue(pixel);
scanline[posx*3+1] = GetGValue(pixel);
scanline[posx*3+2] = GetBValue(pixel);
}
jpeg_write_scanlines(&cinfo, &scanline, 1);
}
jpeg_finish_compress(&cinfo);

jpeg_destroy_compress(&cinfo);
delete scanline;
fclose(outfile);
DeleteDC(hDCmem);
ReleaseDC(desktopWnd, hDC);
return 0;
}