---
title: "TIFF Extra Channels To Spot Color Space"
canonical: https://www.graphicsmill.com/samples/Codecs/SpotColors/TiffExtraChannelsToPdfSpot_cs
product: "Graphics Mill"
source: "Codecs/SpotColors/TiffExtraChannelsToPdfSpot.cs"
---

# TIFF Extra Channels To Spot Color Space

Converts a TIFF file with extra channels to PDF with separation color space.

## Instruction

Write a C# program that reads a TIFF file with extra channels, processes the extra channels, and saves the output in a PDF format with separation color space.

## Usings

```csharp
using System.Collections.Generic;
using Aurigma.GraphicsMill.Codecs;
```

## Code Snippet

```csharp
public static void Run()
{
    using (var reader = new TiffReader("TiffWithExtraChannels.tif"))
    using (var writer = new PdfWriter("TiffWithExtraChannels.pdf"))
    {
        reader.TreatFirstExtraChannelAsAlpha = false;

        Pipeline.Run(reader + writer);

        var names = ParseChannelNames(reader.AdobeResources);

        var displayInfos = ParseDisplayInfo(reader.AdobeResources);

        using (var gr = writer.GetGraphics())
        {
            for (int i = 0; i < reader.Frames[0].ExtraChannels.Count; i++)
            {
                var extraChannel = reader.Frames[0].ExtraChannels[i];

                using (var extraChannelBitmap = extraChannel.GetBitmap())
                using (var spotImage = new Bitmap(extraChannelBitmap.Width, extraChannelBitmap.Height, PixelFormat.Format16bppAspot, RgbColor.White))
                {
                    spotImage.DpiX = extraChannelBitmap.DpiX;
                    spotImage.DpiY = extraChannelBitmap.DpiY;

                    Color color = GetColor(displayInfos[i]);

                    var ink = new Ink(names[i], color)
                    {
                        Solidity = displayInfos[i].Opacity / 100.0f,
                    };

                    spotImage.Ink = ink;
                    extraChannelBitmap.Transforms.Invert();
                    spotImage.Channels[1] = extraChannelBitmap;

                    spotImage.Channels.ScaleAlpha(ink.Solidity);

                    gr.DrawImage(spotImage, 0, 0);
                }
            }
        }
    }
}

private static string[] ParseChannelNames(AdobeResourceDictionary ar)
{
    // https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
    const int unicodeAlphaNames = 0x0415;

    var block = (AdobeResourceBlock)ar[unicodeAlphaNames];

    var names = new List<string>();

    int i = 0;

    while (i < block.Data.Length)
    {
        // skip zeros
        i += 2;

        var length = (block.Data[i] << 8) | block.Data[i + 1];
        i += 2;

        if (length * 2 > block.Data.Length - i)
        {
            throw new System.ArgumentException("Invalid block data.");
        }

        // Get the name without trailing zero
        var name = System.Text.Encoding.BigEndianUnicode.GetString(block.Data, i, (length - 1) * 2);

        i += length * 2;

        names.Add(name);
    }

    return names.ToArray();
}

private static DisplayInfo[] ParseDisplayInfo(AdobeResourceDictionary ar)
{
    // https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
    const int displayInfo = 0x0435;

    var block = (AdobeResourceBlock)ar[displayInfo];

    var displayInfos = new List<DisplayInfo>();

    int i = 4;

    while (i < block.Data.Length)
    {
        var di = new DisplayInfo
        {
            Color = new int[4],
        };

        // Read color space
        di.ColorSpace = (block.Data[i] << 8) | block.Data[i + 1];
        i += 2;

        // Read colors
        for (int j = 0; j < 4; j++)
        {
            di.Color[j] = (block.Data[i] << 8) | block.Data[i + 1];
            i += 2;
        }

        // Read opacity
        di.Opacity = (block.Data[i] << 8) | block.Data[i + 1];
        i += 2;

        di.Kind = block.Data[i++];

        displayInfos.Add(di);
    }

    return displayInfos.ToArray();
}

private static Color GetColor(DisplayInfo di)
{
    if (di.ColorSpace == 0)
    {
        return new RgbColor(
            (byte)(di.Color[0] / 256),
            (byte)(di.Color[1] / 256),
            (byte)(di.Color[2] / 256));
    }
    else if (di.ColorSpace == 2)
    {
        return new CmykColor(
            (byte)(di.Color[0] / 256),
            (byte)(di.Color[1] / 256),
            (byte)(di.Color[2] / 256),
            (byte)(di.Color[3] / 256));
    }
    else
    {
        throw new System.ArgumentException("Unsupported color space.");
    }
}

private struct DisplayInfo
{
    public int ColorSpace;
    public int[] Color;
    public int Opacity;
    public int Kind;
}
```

## Explanation

Below is a C# code sample that demonstrates how to process extra channels in a TIFF file and convert them to a PDF format, applying separation color space.
It reads the TIFF file, extracts extra channels, applies spot color inks, and saves the result into a PDF.

This code handles extra channels in TIFF images, extracts color and opacity information, and writes the result into a PDF file with spot color separation.

## Tags

- [Adobe Resources](<https://www.graphicsmill.com/samples/tags/adobe-resources_md>): Working with Adobe image resource blocks
- [Extra Channels](<https://www.graphicsmill.com/samples/tags/extra-channels_md>): Working with TIFF extra channels
- [Pipeline](<https://www.graphicsmill.com/samples/tags/pipeline_md>): Working with images via the Pipeline API
- [Spot Color](<https://www.graphicsmill.com/samples/tags/spot_md>): Using spot colors in images
- [TIFF](<https://www.graphicsmill.com/samples/tags/tiff_md>): Reading and writing TIFF images

## Input

- [TiffWithExtraChannels.tif](<https://www.graphicsmill.com/samples/Codecs/compiled/Debug/TiffWithExtraChannels_tif>) (download)

## Output

- [TiffWithExtraChannels.pdf](<https://www.graphicsmill.com/samples/Codecs/compiled/Debug/TiffWithExtraChannels_pdf>) (download)
- [TiffWithExtraChannels.png](<https://www.graphicsmill.com/samples/Codecs/compiled/Debug/TiffWithExtraChannels_png>) (preview)

## Used APIs

- [Aurigma.GraphicsMill.Bitmap.Channels](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_Channels.htm.md>)
- [Aurigma.GraphicsMill.Bitmap.DpiX](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_DpiX.htm.md>)
- [Aurigma.GraphicsMill.Bitmap.DpiY](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_DpiY.htm.md>)
- [Aurigma.GraphicsMill.Bitmap.Ink](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_Ink.htm.md>)
- [Aurigma.GraphicsMill.Bitmap.Transforms](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_Transforms.htm.md>)
- [Aurigma.GraphicsMill.ChannelsProvider.ScaleAlpha(Single)](<https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_ChannelsProvider_ScaleAlpha_1_7a94462e.htm.md>)
- [Aurigma.GraphicsMill.CmykColor](<https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_CmykColor.htm.md>)
- [Aurigma.GraphicsMill.Codecs.AdobeResourceBlock](<https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_AdobeResourceBlock.htm.md>)
- [Aurigma.GraphicsMill.Codecs.AdobeResourceBlock.Data](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_AdobeResourceBlock_Data.htm.md>)
- [Aurigma.GraphicsMill.Codecs.AdobeResourceDictionary](<https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_AdobeResourceDictionary.htm.md>)
- [Aurigma.GraphicsMill.Codecs.Frame.GetBitmap](<https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Codecs_Frame_GetBitmap.htm.md>)
- [Aurigma.GraphicsMill.Codecs.ImageReader.AdobeResources](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_ImageReader_AdobeResources.htm.md>)
- [Aurigma.GraphicsMill.Codecs.PdfWriter](<https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_PdfWriter.htm.md>)
- [Aurigma.GraphicsMill.Codecs.PdfWriter.GetGraphics](<https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Codecs_PdfWriter_GetGraphics.htm.md>)
- [Aurigma.GraphicsMill.Codecs.TiffFrame.ExtraChannels](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_TiffFrame_ExtraChannels.htm.md>)
- [Aurigma.GraphicsMill.Codecs.TiffReader](<https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_TiffReader.htm.md>)
- [Aurigma.GraphicsMill.Codecs.TiffReader.Frames](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_TiffReader_Frames.htm.md>)
- [Aurigma.GraphicsMill.Codecs.TiffReader.TreatFirstExtraChannelAsAlpha](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_TiffReader_TreatFirstExtraChannelAsAlpha.htm.md>)
- [Aurigma.GraphicsMill.Color](<https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Color.htm.md>)
- [Aurigma.GraphicsMill.Drawing.Graphics.DrawImage(Bitmap,Single,Single)](<https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawImage_3_b9413d4f.htm.md>)
- [Aurigma.GraphicsMill.Ink](<https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Ink.htm.md>)
- [Aurigma.GraphicsMill.Ink.Solidity](<https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Ink_Solidity.htm.md>)
- [Aurigma.GraphicsMill.TransformsProvider.Invert](<https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_TransformsProvider_Invert.htm.md>)
