Cross-platform C SDK logo

Cross-platform C SDK

Images

❮ Back
Next ❯
This page has been automatically translated using the Google Translate API services. We are working on improving texts. Thank you for your understanding and patience.

Functions

Image*image_from_pixels (...)
Image*image_from_pixbuf (...)
Image*image_from_file (...)
Image*image_from_data (...)
Image*image_from_resource (...)
Image*image_rotate (...)
Image*image_scale (...)
Image*image_copy (...)
Image*image_read (...)
bool_timage_to_file (...)
voidimage_write (...)
voidimage_destroy (...)
voidimage_size (...)
voidimage_format (...)
voidimage_pixels (...)
voidimage_codec (...)
codec_timage_get_codec (...)
uint32_timage_num_frames (...)
real32_timage_frame_length (...)

A digital image, also called bitmap or raster graphics, is a set of small colored dots called pixels organized in a rectangular grid. It is characterized by its resolution (width, height) and depth, which is the amount of bits needed to encode each pixel (Figure 1).

Bitmap images work best for capturing snapshots of the real world, where it is virtually impossible to break the scene into geometric blocks, as we saw in Drawing primitives. On opposite, being composed of discrete points, it does not behave well on size changes where it will suffer a loss of quality.

The same image in two different resolutions.
Figure 1: On the left image of 64x64 pixels and 16 colors. On the right 256x256 pixels and 16 million colors.

1. Load and view images

In most cases, the only thing we will need to know about images will be how to read them from disk or other data source and then display them on the screen as part of the user interface (Listing 1) (Figure 2). We consider that the images are stored in one of the standard formats: JPG, PNG, BMP or GIF.

Listing 1: Loading and viewing images.
1
2
3
4
5
Image *img = image_from_file("lenna.jpg", NULL);
Image *icon = image_from_resource(pack, ekCANCEL);
...
imageview_image(view, img);
button_image(button, icon);
Reading an image from disk and viewing.
Figure 2: Integration of images in the user interface.
NAppGUI only supports JPG, PNG, BMF and GIF formats.

Once the image object is loaded in memory, we have several ways to view it:


2. Generate images

As we saw in 2D Contexts, if necessary we can create our own images from geometric primitives. In Drawing on an image you have a complete sample application (Figure 3).

  • Use dctx_image to create an image from a 2d context.
  • Image generated from drawing commands.
    Figure 3: Image generated by drawing commands.

3. Pixel access

Images are immutable objects optimized for recurring on-screen drawing, so certain licenses are allowed, both in the internal organization of color information and in the management of possible copies. For this reason it is not possible to directly manipulate the pixels, but we must access them using a Pixel Buffer.

Apple technical documentation: "Treat NSImage and its image representations as immutable objects. The goal of NSImage is to provide an efficient way to display images on the target canvas. Avoid manipulating the data of an image representation directly, especially if there are alternatives to manipulating the data, such as compositing the image and some other content into a new image object."

The pixel buffers allow us to optimally manipulate the content of the image. To view the result or store it in any of the supported formats, we must create a new image (Figure 4).

Process from a pixel buffer to an image.
Figure 4: Image editing process.

4. Save images: Codecs

One of the biggest problems of digital images is the large amount of memory they need. An image of only 1024x768 pixels and 32 bits of color needs 3 megabytes of memory. It may not seem like much, but at the end of the 80s this was a great handicap since memory was very expensive and transmissions were very slow. This is why several coding (compression) systems were devised that reduced the amount of memory needed and that were consolidated with the rise of the Internet (Figure 5).

  • Use image_get_codec to get the codec associated with the image.
  • Use image_codec to change the codec associated with the image.
  • Use image_to_file to save it to disk.
  • Use image_write to write it in a Stream.
  • BMP, GIF, JPG and PNG logos.
    Figure 5: Image formats supported by NAppGUI.
  • JPEG: Joint Photographic Experts Group is a format with a very good compression rate based on the Fourier Transform. Ideal for capturing real-world snapshots, although it will detract some quality from the original capture (lossy compression).
  • PNG: Portable Network Graphics emerged in response to legal problems with the GIF format. Supports lossless LZ77/Deflate compression and indexed pixel formats. Ideal for computer generated diagrams, graphics or images.
  • GIF: Graphics Interchange Format uses the proprietary compression algorithm LZW, although the patent expired in 2003. It has survived PNG because it can include animations in a single file, something that neither of the two previous formats supports.
  • BMP: BitMaP. Windows native format widely surpassed by the other three. Although it supports a special type of compression called Run-Length encoding, the truth is that most files are saved uncompressed. BMP files take up much more space, for this reason very little is used on the Internet and almost nothing on non-Windows machines. It is supported by almost all programs and systems because it is very simple an fast to interpret.

To be able to display on the screen, the image must be decompressed (de-encoded), a process that is performed automatically when reading the image. When saving it to disk or sending it over the network, the opposite process is performed, compressed or encoded using the algorithm associated with it (Table 1), but it can be changed.

Table 1: Default image codecs.
Constructor Codec
image_from_file The original codec.
image_from_data The original codec.
image_from_resource The original codec.
image_from_pixels Transparencies? Yes:ekPNG No:ekJPG.
dctx_image ekPNG.

image_from_pixels ()

Create an image from an array of pixels.

Image*
image_from_pixels(const uint32_t width,
                  const uint32_t height,
                  const pixformat_t format,
                  const byte_t *data,
                  const color_t *palette);
width

The image width (in pixels).

height

The image height (in pixels).

format

Pixel format.

data

Buffer that contains the color value of each pixel. It will depend on the resolution and format.

palette

Color palette required to render indexed images. If it is NULL a Predefined palette will be used if necessary.

Return

The image.

Remarks

See Pixel access.


image_from_pixbuf ()

Create an image from a buffer pixel.

Image*
image_from_pixbuf(const Pixbuf *pixbuf,
                  const Palette *palette);
pixbuf

The buffer.

palette

The palette.

Return

The image.

Remarks

Equal to image_from_pixels avoiding indicating parameters separately.


image_from_file ()

Create an image from a file on disk.

Image*
image_from_file(const char_t *pathname,
                ferror_t *error);
pathname

The file path. Filename and pathname.

error

Error code if the function fails. Can be NULL.

Return

The image.

Remarks

Only formats jpg, png, bmp and gif are accepted.


image_from_data ()

Create an image from a buffer containing the encoded data.

Image*
image_from_data(const byte_t *data,
                const uint32_t size);
data

The buffer with the image data.

size

The buffer size in bytes.

Return

The image.

Remarks

The buffer represents data encoded in jpg, png, bmp or gif. To create the image directly from pixels use image_from_pixels.


image_from_resource ()

Get an image of a resource package.

Image*
image_from_resource(const ResPack *pack,
                    const ResId id);
pack

The resource package.

id

The resource identifier.

Return

The image.

Remarks

See Resources.


image_rotate ()

Create a new image by rotating an existing one.

Image*
image_rotate(const Image *image,
             const real32_t angle,
             const bool_t nsize,
             const color_t background);
image

The original image.

angle

Angle in radians.

nsize

TRUE the resulting image will be resized to fit the entire original. FALSE the resulting image will have the same dimensions as the original, cutting part of the content (clipping).

background

Background color. The new image will have "blank" areas due to rotation.

Return

The newly created image.


image_scale ()

Create a copy of the image, with a new size.

Image*
image_scale(const Image *image,
            const uint32_t nwidth,
            const uint32_t nheight);
image

The source image.

nwidth

The width of the new image. Pass UINT32_MAX so that the aspect ratio with respect to nheight.

nheight

The height of the new image. Pass UINT32_MAX so that the aspect ratio with respect to nwidth.

Return

The image.

Remarks

If both values nwidth, nheight are UINT32_MAX or the new dimensions are identical to the current ones, the internal reference counter will increase, as is the case in image_copy.


image_copy ()

Create a copy of the image.

Image*
image_copy(const Image *image);
image

The source image.

Return

The image copy.

Remarks

Images are immutable objects. Copying really means increasing an internal counter without cloning the object. However, the application must destroy the copy with image_destroy just like those created with any other constructor. When all copies are destroyed, it will actually be removed from memory.


image_read ()

Create an image from the data read from a Streams.

Image*
image_read(Stream *stm);
stm

Input stream. Data encoded in jpg, png, bmp or gif are expected. The function detects the format automatically.

Return

The image.


image_to_file ()

Save an image to disk, using the codec associated with it.

bool_t
image_to_file(const Image *image,
              const char_t *pathname,
              ferror_t *error);
image

The image.

pathname

The path of the destination file. Filename and pathname.

error

Error code if the function fails. Can be NULL.

Return

TRUE if it was saved correctly or FALSE and an error has occurred.

Remarks

Use image_codec to change the default codec.


image_write ()

Write an image in an output stream, using the codec associated with it.

void
image_write(Stream *stm,
            const Image *image);
stm

Writing stream. Data encoded in jpg, png, bmp or gif will be written.

image

The image.

Remarks

Use image_codec to change the default codec.


image_destroy ()

Destroy the image.

void
image_destroy(Image **image);
image

The image. Will be set to NULL after destruction.


image_size ()

Get image resolution.

void
image_size(const Image *image,
           uint32_t *width,
           uint32_t *height);
image

The image.

width

The width of the image in pixels.

height

The height of the image in pixels.


image_format ()

Get the pixel format of the image.

void
image_format(const Image *image,
             pixformat_t *format);
image

The image.

format

Pixel format.


image_pixels ()

Get a buffer with the pixels that make up the decoded image.

void
image_pixels(const Image *image,
             const pixformat_t format,
             Pixbuf **pixels,
             Palette **palette);
image

The image.

format

The required pixel format.

pixels

The buffer where the result will be stored. Must be destroyed with pixbuf_destroy.

palette

The color palette for indexed images. Must be destroyed with palette_destroy. It can be NULL.

Remarks

If in pixformat we indicate ekOPTIMAL the format that uses the fewest bits without loss of information will be used. ekFIMAGE will use the original format of the image. For any other value, the conversion will be carried out if necessary.


image_codec ()

Change the default codec associated with the image.

void
image_codec(const Image *image,
            const codec_t codec);
1
2
3
4
Image *img = image_from_file("lenna.jpg", NULL);
Stream *stm = stm_socket(ip, port, NULL, NULL);
image_codec(img, ekPNG);
image_write(socket, img);
image

The image.

codec

The new codec.

Remarks

The change will take effect the next time we save or write the image. By default, the image retains the codec with which it was read. When we create it with image_from_pixels ekJPG codec is assigned as default. For images from 2d contexts dctx_image, the default codec is ekPNG.


image_get_codec ()

Get the codec associated with the image.

codec_t
image_get_codec(const Image *image);
image

The image.

Return

El codec.

Remarks

See image_codec.


image_num_frames ()

Get the number of sequences in animated images.

uint32_t
image_num_frames(const Image *image);
image

The image.

Return

The number of sequences or frames.

Remarks

Only the gif format supports animations. For the rest 1 will always be returned.


image_frame_length ()

Get the time of an animation sequence.

real32_t
image_frame_length(const Image *image,
                   const uint32_t findex);
image

The image.

findex

The frame index.

Return

Sequence time in seconds.

Remarks

Only gif format supports animations.

❮ Back
Next ❯