« FileMaker DevCon Vide… | Home | Menus for Windows com… »

ICC color profiling

We recently got an example about color matching a JPEG file and I want to share this with you.

This code takes a JPEG file, reads it into memory. We pick the ICC profile from the JPEG file. If that is empty, we will substitute it with a generic SRGB profile. For the output profile, you pass it as folderitem to this method, so we need to read it to memory (for embedding later) and also open the profile for doing the color transformation. Now we can create two bitmaps, one for input, one for output. Input bitmap references directly our picture object and output creates a new bitmap with matching size and RGB color space. We create a color transformation with LCMS 2 and process the bitmaps. Now we query the picture and export it with the output profile to disk.

This is the simple version. Included with next plugins is the example project and it includes also an advanced version which uses memory blocks instead of picture object and works with CMYK, Gray and RGB input JPEG files.

Here the code of the method:

Sub Convert(InputFile as FolderItem, OutputFile as FolderItem, ICCProfile as FolderItem) // simple version using picture for RGB only // read picture from JPEG file dim ji as new JPEGImporterMBS ji.ReadProfileData = true ji.File = InputFile ji.Import // we got picture and profile data from source JPEG dim InputPicture as Picture = ji.Picture dim InputProfileData as String = ji.ProfileData // read new profile into memory dim OutputProfileData as string = ReadFile(ICCProfile) dim OutputProfile as LCMS2ProfileMBS = LCMS2ProfileMBS.OpenProfileFromString(OutputProfileData) // now define our input profile dim InputProfile as LCMS2ProfileMBS if InputProfileData = "" then // use SRGB profile InputProfile = LCMS2ProfileMBS.CreateSRGBProfile InputProfileData = InputProfile.SaveProfileToString else // use profile in file InputProfile = LCMS2ProfileMBS.OpenProfileFromString(InputProfileData) end if // now create input picture using given bitmap dim bi as new LCMS2BitmapMBS(InputPicture) // and create RGB output bitmap with same size dim bo as new LCMS2BitmapMBS(InputPicture.Width, InputPicture.Height, LCMS2MBS.kcmsSigRgbData) // pick formats dim InputFormat as integer = InputProfile.FormatterForColorspace(1) dim OutputFormat as integer = OutputProfile.FormatterForColorspace(1) // now do transform dim ct as LCMS2TransformMBS = LCMS2TransformMBS.CreateTransform(InputProfile, InputFormat, OutputProfile, OutputFormat, LCMS2MBS.kINTENT_RELATIVE_COLORIMETRIC, 0) call ct.Transform(bi, bo) // we get back output picture dim OutputPicture as Picture = bo.Picture bo = nil bi = nil // and write to disk dim je as new JPEGExporterMBS je.Quality = 90 je.ProfileData = OutputProfileData je.File = OutputFile je.Picture = OutputPicture je.Export End Sub
01 09 14 - 11:23