>
> I'm reading a bitmap image form the current window or off
> screen buffer
> by using given below API
>
> uchar * fl_read_image ( uchar *p , int x, int y, int w , int
> h , int alpha
> =0); with buffer of X*Y*3
>
>
>
> I could able to save image in the file. But the size of the
> file is around 1
> MB in case of 600*600 pixels.
>
>
>
> I want to reduce the size of file. How to do that?
Your best bet is just to save the file as a PNG or a JPEG - both
libraries are bundled with fltk, including their supporting docs and
examples, so it is pretty easy to just copy one of their examples - both
PNG and JPEG can be passed a byte array as returned by fltk and store it
to a file for you.
(Both also have annoyingly fiddly interfaces!)
Fltk does not provide any wrapper functions to do this - it is "the
same" on all supported platforms, so you are better off just using your
own code to do that.
> Why need to create buffer of X*Y*3 in case of bitmap image if
> it is image
> like jpeg image (RGB components). Ok
Sorry, I don't think I understood this part...?
OK - this is going to make the post a lot longer, but here's a crude
worked example of how to write a byte array to a JPEG file. I think this
works, you may need to check it thoroughly to be sure!
----------------------------------
#ifndef HAVE_WRITE_JPEG_H
#define HAVE_WRITE_JPEG_H
#ifndef WRITE_DATA_ERROR
# define WRITE_DATA_ERROR -1
#endif
#ifndef WRITE_DATA_OK
# define WRITE_DATA_OK 0
#endif
#ifndef MAX_JPG_COM_LENGTH
# define MAX_JPG_COM_LENGTH 65000L /* must be <= 65533 in any case
*/
#endif
/* Allow C++ Portability */
#ifdef __cplusplus
extern "C" {
#endif
/* write a JPEG file */
extern
int write_jpg (char *file_name, /* Name of file to be written */
unsigned char *datap, /* pointer to image data
array */
int width, /* Image width
*/
int height, /* Image height
*/
int depth, /* Image depth,
valid values 1(mono), 3(RGB) */
char *keyword, /* Keyword to
use in COM chunk (may be NULL) */
char *description); /* String to use in COM
chunk (may be NULL) */
/* NOTE: As a special case, setting quality to 0 just uses the default
settings */
extern void set_jpg_quality (int quality); /* Set image quality param (0
- 100) */
extern int get_jpg_quality (void); /* Read current quality setting */
/* Allow C++ Portability */
#ifdef __cplusplus
}
#endif
#endif /* HAVE_WRITE_JPEG_H */
/* End of File */
-----------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <jpeglib.h>
#include "write_jpg.h"
/* Holds Global quality setting - accessed only by the accessor methods
provided */
static int quality = 0; /* Image quality param (0 - 100) (0 uses lib
defaults) */
/***********************************************************************
*********/
void set_jpg_quality (int iv)
{
if (iv < 0) iv = 0;
else if (iv > 100) iv = 100;
quality = iv;
}
/***********************************************************************
*********/
int get_jpg_quality (void)
{
return quality;
}
/***********************************************************************
*********/
int write_jpg (char *file_name, // Name of file to be written
unsigned char *datap, // pointer to image data
array
int width, // Image width
int height, // Image height
int depth, // Image depth,
valid values 1(mono), 3(RGB)
char *keyword, // Keyword to
use in COM chunk (may be NULL)
char *description) // String to use in COM
chunk (may be NULL)
{
struct jpeg_compress_struct cinfo;
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 */
char *com_block_txt; /* Used to hold any COM block we
write out */
/* Only handle RGB or Greyscale images for now */
if ((depth != 3) && (depth != 1))
{
return WRITE_DATA_ERROR;
}
com_block_txt = NULL;
/* Setup jpeg error handling */
cinfo.err = jpeg_std_error (&jerr);
/* Now we can initialise the JPEG compression object. */
jpeg_create_compress (&cinfo);
/* Open the output file */
if ((outfile = fopen (file_name, "wb")) == NULL)
{
//fprintf (stderr, "can't open %s\n", file_name);
return WRITE_DATA_ERROR;
}
jpeg_stdio_dest (&cinfo, outfile);
/* Setup compression parameters */
cinfo.image_width = width; /* image width and
height, in pixels */
cinfo.image_height = height;
cinfo.input_components = depth; /* number of bytes per pixel */
if (depth == 3)
{
cinfo.in_color_space = JCS_RGB; /* RGB input image */
}
else
{
cinfo.in_color_space = JCS_GRAYSCALE; /* Greyscale input
image */
}
/* Now use the library routine to set default compression
parameters. */
jpeg_set_defaults (&cinfo);
/* Do we want to override the default compression quality? */
if (quality > 10)
{
jpeg_set_quality (&cinfo, quality, TRUE);
}
/* Start compressor */
jpeg_start_compress (&cinfo, TRUE);
/* Now we have started the compressor, do we have a COM chunk to
write out? */
if ((keyword != NULL) && (description != NULL))
{
unsigned int ulen = strlen(keyword) +
strlen(description);
if ((ulen > 0) && (ulen < MAX_JPG_COM_LENGTH))
{
com_block_txt = malloc(ulen + 8);
sprintf(com_block_txt, "%s: %s", keyword,
description);
jpeg_write_marker(&cinfo, JPEG_COM, (JOCTET
*)com_block_txt, strlen(com_block_txt));
}
}
/* Cycle through the input data, writing out the image */
row_stride = width * depth; /* JSAMPLEs per row in
image_buffer */
while (cinfo.next_scanline < cinfo.image_height)
{ /* For each data line... */
row_pointer[0] = &datap[cinfo.next_scanline *
row_stride];
jpeg_write_scanlines (&cinfo, row_pointer, 1);
}
/* Finish compression */
jpeg_finish_compress (&cinfo);
/* Now close the output file. */
fclose (outfile);
/* Free the JPEG compression object and other allocated memory
*/
jpeg_destroy_compress (&cinfo);
if (com_block_txt) free(com_block_txt);
/* And we're done! */
return WRITE_DATA_OK;
}
/***********************************************************************
*********/
#ifdef STANDALONE_FUNCTION_TEST
int main (void)
{
int w, h, d;
unsigned char * datap;
int idx, jdx;
int res;
char desc[512];
w = h = 256;
d = 3;
datap = malloc(w * h * d);
for (idx = 0; idx < h; idx ++)
{
for (jdx = 0; jdx < w; jdx++)
{
int cell = (idx * h * d) + (jdx * d);
datap[cell] = jdx;
datap[cell + 1] = (idx + jdx) & 0xFF;
datap[cell + 2] = idx;
}
}
set_jpg_quality (0); /* Set quality to default */
res = get_jpg_quality();
if (res) puts("Quality setting failed");
sprintf(desc, "Test Image - version 0\nsize %d %d %d", w, h, d);
res = write_jpg ("Jtest1.jpg", datap, w, h, d, "Test1", desc);
if (res) puts("T1 failed");
free(datap);
d = 1;
datap = malloc(w * h);
for (idx = 0; idx < h; idx ++)
{
for (jdx = 0; jdx < w; jdx++)
{
int cell = (idx * h) + jdx;
datap[cell] = jdx;
}
}
sprintf(desc, "Test Image - version 2\nsize %d %d %d\nThis is
Mono\ndone!", w, h, d);
res = write_jpg ("Jtest2.jpg", datap, w, h, d, "Test2", desc);
if (res) puts("T2 failed");
free(datap);
if(!res)
puts("JPEG write done!");
return 0;
}
#endif
/***********************************************************************
*********/
/* End of File */
-----------------------------------------------
SELEX Sensors and Airborne Systems Limited
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14
3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk