TIFF Extra Channels To Spot Color Space
TIFF Extra Channels Spot Color Adobe Resources Pipeline
Converts a TIFF file with extra channels to PDF with separation color space.
Сode Snippet
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;
}
Input
TiffWithExtraChannels.tif
DownloadOutput
TiffWithExtraChannels.pdf
DownloadTiffWithExtraChannels.png
For AI-assisted development: Download Graphics Mill Code Samples XML Catalog