---
title: "Compressed Image"
canonical: https://www.graphicsmill.com/docs/gm/compressed-image.htm
archived: false
applies_to:
  - product: "Graphics Mill"
    versions: ["12.1", "6.x-12.x (may differ)"]
    entity_id: "https://www.graphicsmill.com/#software-application"
---

# Compressed Image

**Applies to:** Graphics Mill 12.1, 6.x-12.x (may differ)
 
**CompressedImage** is an image type that stores raster data in compressed form instead of fully unpacking it into memory.
 
This feature was introduced primarily to increase the efficiency of getting PDF content in the form of a [GraphicsContainer](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_GraphicsContainer.htm.md). Previously, images were represented only as **Bitmap**, which always keeps raster data decompressed in memory. Now both **Bitmap** and **CompressedImage** derive from the common base class **Image**:
 
- **Image** stores common image parameters.
- **Bitmap** stores fully decoded pixel data in memory.
- **CompressedImage** stores image data as compressed streams.

This approach is especially useful when working with PDF content.
 
## Why use CompressedImage
  
In most cases, you do not need to create or read **CompressedImage** objects manually.
 
The main scenario is PDF processing. When Graphics Mill reads PDF content, it can keep image data as compressed streams whenever possible. These streams remain compressed until you explicitly rasterize them.
 
This provides two important benefits:
 
- **Lower memory usage** because image data is not decompressed until needed.
- **More efficient PDF round-tripping** because image streams can be written back to a PDF without unpacking and recompressing them.

If you save such content back to PDF, the original compressed stream can be reused as-is.
 
## When to create a CompressedImage manually
  
Manual creation of a **CompressedImage** is an advanced scenario.
 
Typically, you only need it when you want more control over how images are compressed in generated PDF files.
 
**CompressedImage** exposes two separate streams:
 
- **ColorStream**
- **AlphaStream**

This matches the internal representation used by PDF images, where color and alpha data may be stored separately. In general, these streams may even have different dimensions.
 
However, if you create a **CompressedImage** manually, the color and alpha parts always correspond to the same image dimensions.
 
## Create a CompressedImage from a pipeline
  
Use this approach when you want to build a compressed image from an image source and explicitly choose the compression type.
 
```csharp
using (var reader = ImageReader.Create(@"Images\in.jpg"))
{
    var pipeline = new Pipeline();
    pipeline.Add(reader);

    using (var compressedImage = CompressedImage.CreateFromPipeline(pipeline, CompressionType.Zip))
    {
        Console.WriteLine("Image width: " + compressedImage.Width);
        Console.WriteLine("Image height: " + compressedImage.Height);
        Console.WriteLine("Compression: " + compressedImage.ColorStream.Compression);
        Console.WriteLine("Stream size: " + compressedImage.ColorStream.Size);
    }
}
```
 
## Create a CompressedImage from a file
  
You can also create a compressed image directly from a file:
 
```csharp
using (var compressedImage = CompressedImage.CreateFromFile(@"Images\in.jpg", CompressionType.Zip))
{
    Console.WriteLine("Image width: " + compressedImage.Width);
    Console.WriteLine("Image height: " + compressedImage.Height);
    Console.WriteLine("Compression: " + compressedImage.ColorStream.Compression);
    Console.WriteLine("Stream size: " + compressedImage.ColorStream.Size);

    using (var bitmap = compressedImage.GetBitmap())
    {
        bitmap.Transforms.Resize(500, 500, ResizeInterpolationMode.High, ResizeMode.Fit);
        bitmap.Save(@"Images\Output\out.jpg");
    }
}
```
 
## Keep the encoded data of PNG and JPEG files
  
Call [CompressedImage.CreateFromFile(String)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_CompressedImage_CreateFromFile_1_bb3a7a4f.htm.md) or [CompressedImage.CreateFromStream(Stream)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_CompressedImage_CreateFromStream_1_bca7c9fe.htm.md) without a compression type. If the source is a PNG or JPEG image, the encoded data is kept as is. The image is not decoded and compressed again. The **ColorStream.Compression** property returns **Png** or **Jpeg**.
 
```csharp
using (var compressedImage = CompressedImage.CreateFromFile(@"Images\in.jpg"))
{
    // The compression is Jpeg, because the JPEG data of the file is kept as is.
    Console.WriteLine("Compression: " + compressedImage.ColorStream.Compression);
    Console.WriteLine("Stream size: " + compressedImage.ColorStream.Size);
}
```
 
When you draw such an image to a PDF document, the data is embedded without recompression. This is fast, and the colors of the image stay unchanged. It works for CMYK JPEG images too.
 
Other formats are decoded and compressed with **Zip**. A PNG image with an alpha channel is also decoded, because **CompressedImage** stores alpha in a separate stream.
 
The same applies when you read a PDF file. A JPEG image that is stored in the file stays compressed. This includes CMYK JPEG images that Graphics Mill wrote to the file before. If the PDF file has large images, set [PdfReader.CompressedImageThreshold](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_PdfReader_CompressedImageThreshold.htm.md) to keep the data of the images in temporary files instead of in memory.
 
## CMYK JPEG images and Adobe Illustrator
  
The PDF writer adds an inverting entry to the **Decode** parameter of a CMYK JPEG image that you created from a file with the encoded data kept as is. PDF viewers show such an image correctly, and the PDF file is valid. Adobe Illustrator reads the image with inverted colors.
 
If you need compatibility with Adobe Illustrator, recompress such an image before you draw it. The sample below checks that the image is a CMYK JPEG and creates a new compressed image from it:
 
```csharp
using (var pdfWriter = new PdfWriter(@"Images\Output\CmykJpeg.pdf"))
using (var graphics = pdfWriter.GetGraphics())
{
    pdfWriter.AddPage(new PdfPage()
    {
        Width = 595,
        Height = 842
    });

    using (var compressedImage = CompressedImage.CreateFromFile(@"Images\cmyk.jpg"))
    {
        if (compressedImage.ColorStream.Compression == CompressionType.Jpeg &&
            compressedImage.PixelFormat.ColorSpace == ColorSpace.Cmyk)
        {
            // Decode the JPEG and compress it again to get a regular CMYK JPEG stream.
            using (var recompressedImage = CompressedImage.CreateFromPipeline(compressedImage, CompressionType.Jpeg, new JpegSettings()))
            {
                graphics.DrawImage(recompressedImage, 0, 0);
            }
        }
        else
        {
            graphics.DrawImage(compressedImage, 0, 0);
        }
    }
}
```
 
## What you can do with a CompressedImage
  
A **CompressedImage** is intended mainly for inspection and deferred rasterization.
 
You can:
 
- inspect image properties such as width and height;
- inspect compression settings;
- check compressed stream sizes;
- keep image data compressed until rasterization is actually needed.

This can be useful in preflight and optimization scenarios.
 
## Access pixel data
  
**CompressedImage** does not provide direct pixel-level editing. If you need to access or modify pixels, convert it to a **Bitmap** first:
 
```csharp
using (var compressedImage = CompressedImage.CreateFromFile(@"Images\in.jpg", CompressionType.Zip))
using (var bitmap = compressedImage.GetBitmap())
{
    bitmap.Transforms.Resize(500, 500, ResizeInterpolationMode.High, ResizeMode.Fit);
    bitmap.Save(@"Images\Output\out.jpg");
}
```
