주요 내용으로 건너뛰기

이미지 압축

TouchGFX는 버전 4.22부터 이미지 압축 기능을 지원합니다. The support from version 4.22 to 4.23 inclusive is limited to compression of L8 images. From version 4.24 compression of RGB565, RGB888, and ARGB8888 image formats is supported.

이미지 압축은 이미지에 대한 저장 공간 요구 사항을 줄여주는 프로세스입니다. 프로젝트에서 이미지 크기가 줄면 더 작은 플래시를 사용해서 비용을 절감할 수 있습니다. 또한, 프로젝트에서 더 많은 이미지를 사용할 수 있기 때문에 보다 풍부한 UI를 구현하는 것이 가능합니다.

이미지 압축은 일반적으로 무손실 압축과 손실 압축 두 가지 방식이 있습니다. 손실 압축은 이미지의 사소한 세부 사항을 제거해서 압축을 합니다. 크기는 최대한 줄일 수 있지만, 원본 이미지를 정확하게 재현할 수 없는 경우가 많습니다. 무손실 압축은 항상 원본 이미지를 그대로 재현합니다. 또한, 무손실 압축은 일반적으로 이미지의 크기를 줄여줍니다.

그래픽의 경우에 UI 요소를 디자인한 대로 정확히 드로잉해야 하는 경우가 많습니다. 이러한 이유로 TouchGFX는 무손실 압축만 지원하고 있습니다.

이미지 압축은 크기를 줄일 수 있다는 장점이 있지만, 이미지를 프레임 버퍼에 그릴 때 압축을 해제해야 한다는 단점도 있습니다. 압축되지 않은 이미지를 그릴 때와 비교해 이러한 압축 해제를 위해서는 많은 경우에 CPU에서 더 많은 작업이 필요합니다. 그 결과, 성능 저하가 발생할 수 있습니다.

따라서 플래시 공간 감소로 얻는 이점과 CPU 사용량 증가로 인한 단점을 비교해야 합니다.

많은 STM32 마이크로컨트롤러에 존재하는 DMA2D 및 GPU2D(ChromART 및 NeoChrom GPU) 그래픽 가속기는 압축된 이미지를 직접 그릴 수 없다는 점에 유의하십시오. Compressed images are drawn using a mix of software and hardware rendering, i.e. the compressed data is decompressed in chunks by software and these chunks are then delegated to the DMA2D where applicable.

많은 애플리케이션에서 모든 이미지를 압축하는 것이 아니라, 성능이 손상되지 않고 플래시 공간 감소가 가능한 경우에만 이미지를 압축하도록 권장하고 있습니다. See also the section below about decompression to the Bitmap cache as a mean to get both lower storage requirement and good performance.

L8 압축

위에서 언급했듯이 TouchGFX 4.22는 L8 이미지 압축을 지원합니다. L8 비트맵 형식은 최대 256가지 색상이 지원되는 이미지에만 적합합니다. 각 픽셀은 이미지와 함께 저장된 컬러 테이블의 색상을 나타내는 8비트 숫자일 뿐입니다. The compression of an L8 is only compression of the pixel numbers. 컬러 테이블은 그대로 둡니다.

아래 이미지를 예로 들어보겠습니다. 이미지가 미터링 애플리케이션에서 배경으로 사용되는 경우입니다.

L8-ARGB8888

이미지는 184 x 184 픽셀입니다. The size of the pixel data is thus 184 x 184 = 33,856 bytes.

If we compress the image the pixel data is reduced to 5,735 bytes. The total size of the compressed image data, including the color table, is less than 20% of the original image. Compression thus allows us to have 5 different backgrounds in the same flash space, or to reduce the flash requirements by 28,121 bytes.

압축된 L8 이미지는 일반적인 비압축 비트맵처럼 사용됩니다. 예를 들어 TouchGFX Designer 또는 코드에서 프로젝트를 수정하지 않고도 이미지 위젯을 사용해 이미지를 표시할 수 있습니다. This makes use of compressed L8 images very easy.

3 algorithms #{three-algorithms}

TouchGFX uses 3 different compression algorithms for the L8 format. The image converter selects the algorithm that gives the best compression, unless the user has mandated a specific algorithm in the configuration. The algorithms are:

  • L4는 각 픽셀을 4비트로 인코딩하고, 최대 16가지 색상이 지원되는 이미지에만 적용할 수 있습니다.
  • RLE는 픽셀의 실행 길이를 인코딩하고, 최대 64가지 색상이 지원되는 이미지에만 적용할 수 있습니다.
  • LZW9은 딕셔너리를 기반으로 인코딩을 수행하고, 모든 L8 이미지에 적용할 수 있습니다.

RLE 알고리즘은 LZW9보다 압축 해제 속도가 훨씬 빠르다는 점에서 이미지 변환 프로그램은 LZW9의 이미지 압축 성능이 약간 더 나은 경우에는 RLE를 선택합니다.

RGB Compression

As mentioned earlier, TouchGFX 4.24 introduced image compression support for the RGB565, RGB888, and ARGB8888 image formats. Images which contains more than 256 unique colors cannot be stored in the compact L8 image format and must be stored in one of the aforementioned formats. The compression of an RGB565, RGB888, or ARGB8888 image is directly compressing the 16-, 24-, or 32-bit pixels.

아래 이미지를 예로 들어보겠습니다. It is a more complex and rich background than the above example and has more than 256 unique colors. Therefore, it cannot be stored in L8, and it must be stored in the ARGB8888 format because it has transparent pixels (in the corners).

ARGB8888

The image is 240 x 240 pixels. The size of the pixel data is thus 240 x 240 x 4 = 230.400 bytes because we use 4 bytes to store each pixel in the ARGB8888 image format.

Compressing the image reduces the size to 32.347 bytes. The size of the compressed image is considerably smaller and only 14% of the original image size. Compression allows us to have multiple complex backgrounds in the same flash space, or reduce the flash requirements by a substantial amount. It also enables flash-limited devices to adopt more complex and rich graphics than otherwise possible with the L8 formats.

A compressed RGB image can be used like an ordinary uncompressed bitmap. 예를 들어 TouchGFX Designer 또는 코드에서 프로젝트를 수정하지 않고도 이미지 위젯을 사용해 이미지를 표시할 수 있습니다. This makes use of compressed RGB images very easy.

Caution
Applying any dithering algorithm to an RGB image can in some cases compromise the effectiveness of the RGB compression.

2 algorithms

TouchGFX uses 2 slightly different compression algorithms which are automatically selected based on the image format to be compressed. The algorithms are:

  • QOI, encodes RGB888 and ARGB8888 pixels using a variation of the Quite OK Image format compression algorithm.
  • QOI565, encodes RGB565 pixels using a variation of QOI that is tailored for 16-bit pixel values.

Both variants of the RGB Compression algorithms are optimized for fast decompression speeds to limit the run-time performance penalty when rendering compressed RGB images.

Working with Compressed Images

Enabling the Image Compression Features

Image compression requires extra code in the target application. To avoid this higher space requirements, the compression code is optional on some platforms. You may have to enable the feature for your project.

Click "Config" on the left of the Designer, then click "Framework Features"

Enabling image compression

The image compression features are shown in the bottom. You can enable the specific feature set you need.

The targets has different options for the framework features, and in some cases the target has no optional features as shown below:

No optional framework features

In this case all the features are always enabled.

Caution
Be aware that the Designer does not show an error or warning if you use a feature that is not enabled. If you use image compression and the features is not enabled, the image is not drawn.

L8 압축

압축된 이미지는 일반 이미지와 똑같이 사용됩니다. TouchGFX Designer에서 비트맵을 사용하도록 위젯을 구성하거나, 코드에서 비트맵을 할당할 수 있습니다.

L8-ARGB8888 이미지에 대한 압축 구성

Compression 값을 "Auto"로 설정하기만 하면 됩니다. 이미지 변환 프로그램은 최적의 압축을 자동으로 선택하거나, 이미지를 압축할 수 없는 경우에는 어떤 것도 선택하지 않습니다.

위젯에서 압축 이미지 선택

이제는 평소처럼 위젯에 대한 이미지를 선택할 수 있습니다. 압축되지 않은 이미지와 비교해도 이 부분에서는 차이가 없습니다.

코드에서 이미지를 사용할 때도 별다른 차이가 없습니다. 압축된 비트맵은 평소와 같이 BitmapID를 사용하여 참조됩니다.

    image1.setXY(148, 148);
image1.setBitmap(touchgfx::Bitmap(BITMAP_GAUGE_BACKGROUND_ID));

압축된 L8 이미지에 대한 자세한 내용은 여기에서 확인하십시오.

RGB Compression

Compressing RGB565, RGB888, or ARGB8888 images in the TouchGFX Designer follows the same process as L8 compression.

L8-ARGB8888 이미지에 대한 압축 구성

If selecting "Yes" the Image Converter will compress the image with the algorithm that matches the image format.

As with the L8 Compression, we can select the image for a widget as normal and reference the bitmap in code as usual.

압축 수준

이미지 변환 프로그램이 선택한 압축 알고리즘이 생성된 파일에 기록됩니다. 여기에서 압축 수준을 확인할 수도 있습니다.

The image we used above in the L8 Compression example is generated into the file generated/images/src/image_gauge_background.cpp. The header of this file reads:

image_gauge_background.cpp (extract)
// 4.22 D0 AN R0 FL8_ARGB8888 U888 N0 SExtFlashSection EExtFlashSection CL8_LZW9

LOCATION_PRAGMA("ExtFlashSection")
KEEP extern const unsigned char image_gauge_background[] LOCATION_ATTRIBUTE("ExtFlashSection") = {
// 184x184 L8_ARGB8888 pixels. Compression [output/input x 100]: 5735/33856 x 100 = 16.9%
0x00, 0x26, 0x50, 0xa8, 0x60, 0xe1, 0x02, 0x86, 0x0c, 0x1a, 0x36, 0x70,
....

The end of the comment in the first line shows the compression algorithm. 여기에서 Image Converter가 LZW9 알고리즘을 선택했음을 확인할 수 있습니다. 라인 5의 끝을 보면 원본이 33856 바이트인 것과 달리 현재 픽셀 데이터는 5735 바이트라는 것을 알 수 있습니다. 압축 결과는 16.9%입니다(압축 수준은 작을수록 좋음). 주의! The compression percentage does not count the color table.

Compression Failure

In some cases the Image Converter gives a warning or error when compressing images. This can happen if the image is not compatible with the selected algorithm, or if the size of the compressed image is not below 90% of the original image. This will only happen in very rare coincidences. For example if a small image of 5 x 5 uses 25 different and distinct colors. Since there is no repetition or redundancy in the image, there is no possibilities for the compression to reduce the data.

L8 Images

For L8 images this can happen if a specific algorithm was selected that does not match the given image. For example if an image contains 17 colors or more, and and L4 compression is selected, the image can not be compressed using the selected algorithm. The Image Converter will print an error message when you generate code, and the Designer will show an error message:

Compression error with specific algorithm

The solution to the problem is to use another algorithm. The preferred way is to select "Auto" for L8 images. Then the image converter will try all algorithms, and select the best algorithm of those who are applicable.

In some rare cases the image does not compress below 90% of the original size. The Image Converter does not compress the image in that case and issues a warning text as shown below:

Compression warning

The reason for not compressing is that the saving in flash size does not outweigh the lower rendering performance. It is possible to force the compression by not using "Auto" but selecting one of the algorithms ("L4", "RLE", or "LZW").

The warning message is only informational. The code generation continues and the project will work as expected.

RGB Images

For RGB image formats you can not select the "Auto", as there is only one compression algorithm. If you select "Yes" and the image is not compressible below 90% of the original size, the Image Converter will generate an error:

Compression error with RGB image

The solution here is to select "None" for Compression for the image.

Decompressing Images to the Bitmap Cache

대부분의 경우에 압축된 이미지를 그릴 때가 압축되지 않은 이미지를 그릴 때보다 성능이 떨어집니다. Further more, as mentioned in the introduction, the graphics accelerators in STM32 micro-controllers (DMA2D and GPU2D) cannot draw the compressed images directly. Therefore, compressed images are drawn by a mix of software and hardware, resulting in lower performance and higher cpu-load.

이러한 이유로 TouchGFX에는 런타임에서 압축 이미지를 RAM의 비트맵 캐시로 압축 해제하는 기능도 포함되어 있습니다.

이미지를 RAM으로 압축 해제하면 그리기 성능은 압축되지 않은 이미지를 사용할 때와 비슷하지만, 가속기가 이미지를 그릴 수 있습니다.

압축을 해제할 수 있으려면 먼저 비트맵 캐시를 설정해야 합니다. 비트맵 캐시 사용에 대한 자세한 내용은 여기에서 확인하십시오.

비트맵 캐시를 설정한 후에는 Bitmap::decompress 함수를 사용해 이미지의 압축을 해제할 수 있습니다. 아래와 같이 전체 코드가 표시됩니다.

// Define an array for the bitmap cache
uint16_t cache[20*1024]; //40 KB cache
// Define an array for the decompression temporary buffer
uint16_t lzwBuffer[1024];

void TemplateView::setupScreen()
{
...
Bitmap::setCache(cache, sizeof(cache)); // Register the bitmap cache
bool r = Bitmap::decompress(BITMAP_GAUGE_BACKGROUND_ID, lzwBuffer); // Decompress the bitmap
image1.setBitmap(touchgfx::Bitmap(BITMAP_GAUGE_BACKGROUND_ID)); // Use the bitmap as normal
image1.setXY(148, 148); // Position Image widget
}

In this example we want to decompress the 184 x 184 image from the L8 Compression example above into the bitmap cache. The bitmap cache must be big enough to the hold uncompressed image. The 184 x 184 pixels plus the color table holding 207 ARGB8888 colors. The total size is therefore 34,688 bytes.

In this example we use the LZW9 algorithm. A 2048 bytes buffer is used by the decompresser during the decompression of an LZW9 compressed image (for building a dictionary). The buffer is not required after the decompression and can be reused for other purposes. The buffer is not required for decompression of L4, RLE, QOI, or QOI565 compressed images.

압축을 해제한 이미지를 더 이상 사용하지 않을 때는 Bitmap::cacheRemoveBitmap 메소드를 사용해 비트맵 캐시에서 이를 제거할 수 있습니다.

Limit program size

If you use decompression into the bitmap cache you have a few options to limit the size of your program. As mentioned above there are two types of image compression; L8 and RGB. When using Bitmap::decompress your program will contain the code for both decompressing L8 and RGB images. If you only use the RGB image compression, you can use the dedicated method for decompressing RGB images into the bitmap cache, which is Bitmap::decompressRGB, that way your program will only contain the required code for decompressing RGB images. The same applies if you only use L8 compression, here the method is called Bitmap::decompressL8. See examples below.

void TemplateView::setupScreen()
{
...
// Decompress the bitmap (RGB using QOI)
bool r = Bitmap::decompressRGB(BITMAP_GAUGE_BACKGROUND_ID);
...
}
void TemplateView::setupScreen()
{
...
// Decompress the bitmap (L8 using RLE, no buffer required)
bool r = Bitmap::decompressL8(BITMAP_GAUGE_BACKGROUND_ID);
...
}

제한 사항

There are a few limitations when working with compressed images. Compressed images cannot be used with Widgets that scales or rotates the image, or with Widgets that fills an area, or with the Canvas widgets.

호환되지 않는 위젯과 함께 압축 이미지 사용.

Caution
압축된 이미지를 모든 위젯에서 사용할 수 있는 것은 아닙니다. TouchGFX Designer는 경고 아이콘을 제공합니다.

These limitations are made for performance reasons. TouchGFX Designer에서는 압축된 이미지를 선택하도록 허용하지 않습니다.

If you want to use a specific image with any of these Widgets we suggest to not enable compression for the image. Alternatively, you can decompress the image at runtime.

압축 이미지를 지원하지 않는 위젯은 다음과 같습니다.

  • TextureMapper
  • ScalableImage
  • 바늘 및 아크용 Gauge
  • 그래프 아래 영역을 채우기 위한 StaticGraph 및 DynamicGraph
  • 손목용 AnalogClock
  • 원, 라인 및 쉐이프
  • CircleProgress 및 LineProgress