Welcome Guest! You need to login or register to make posts.

Notification

Icon
Error

Options
Go to last post Go to first unread
camelord  
#1 Posted : Wednesday, January 10, 2007 11:15:23 PM(UTC)
camelord

Rank: Member

Groups: Member
Joined: 5/31/2006(UTC)
Posts: 20

Hi,

i want to draw a text onto a CMYK Image.
i tried

Code:
Aurigma.GraphicsMill.Drawing.GdiGraphics g = theTiffImage.GetGdiGraphics();
g.DrawString("test test test", new Aurigma.GraphicsMill.Drawing.Font("Arial", 15), new Aurigma.GraphicsMill.Drawing.SolidBrush((Aurigma.GraphicsMill.RgbColor)(getRGBColor(0, 0, 0, 255))), new Point(50, 50));


where getRgbColor is a Function to convert CYMK values (byte) into RGBColor. Unfortunatly this is nessecary, because you can't draw in CMYK..

Well, the line
Code:
Aurigma.GraphicsMill.Drawing.GdiGraphics g = theTiffImage.GetGdiGraphics();

returns an Error: 'Format not supported'

How can i draw a text onto a CMYK Image?

regards

Christian

Edited by user Tuesday, December 18, 2007 4:50:05 PM(UTC)  | Reason: Not specified

Dmitry  
#2 Posted : Thursday, January 11, 2007 5:26:37 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
Hello,

GdiGraphics cannot work with CMYK pixel formats. Nevertheless Graphics Mill for .NET supports drawing of strings on CMYK bitmaps. The basic idea is to draw text string on temporary transparent RGB bitmap, then convert it to CMYK format and draw it on destination image. Here is code sample which illustrates how to do it:
Code:
string str = "Aurigma";
System.Drawing.SizeF size = System.Drawing.SizeF.Empty;
System.Drawing.Font font = new System.Drawing.Font("Arial", 14);
System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Red);
Aurigma.GraphicsMill.Bitmap bmp = new Aurigma.GraphicsMill.Bitmap(@"d:/images/test/cmyk32.jpg");
	
// Measure string.
Aurigma.GraphicsMill.Bitmap tempBmp = new Aurigma.GraphicsMill.Bitmap(100, 100, 
    Aurigma.GraphicsMill.PixelFormat.Format24bppRgb);
System.Drawing.Graphics gdipGraphics = tempBmp.GetGdiplusGraphics();
try
{
	size = gdipGraphics.MeasureString(str, font);
}
finally
{
	gdipGraphics.Dispose();
	tempBmp.Dispose();
}
	
// Create temporary bitmap 32bpp ARGB bitmap and draw string on it.
Aurigma.GraphicsMill.Bitmap textBitmap = new Aurigma.GraphicsMill.Bitmap(System.Convert.ToInt32(size.Width), 
    System.Convert.ToInt32(size.Height), Aurigma.GraphicsMill.PixelFormat.Format32bppArgb);
System.Drawing.Bitmap gdipBitmap = textBitmap.ToGdiplusBitmapDirectly();
gdipGraphics = System.Drawing.Graphics.FromImage(gdipBitmap);
try
{
	gdipGraphics.DrawString(str, font, brush, 0, 0);
}
finally
{
	gdipGraphics.Dispose();
	gdipBitmap.Dispose();
}
	
// Convert temporary bitmap with string to CMYK pixel format and draw it on destination bitmap.
textBitmap.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.Cmyk, 
    textBitmap.HasAlpha, textBitmap.IsExtended);
textBitmap.Draw(bmp, 20, 20, textBitmap.Width, textBitmap.Height, Aurigma.GraphicsMill.Transforms.CombineMode.Alpha, 
    1.0f, Aurigma.GraphicsMill.Transforms.InterpolationMode.LowQuality);

bmp.Save(@"d:/temp/CmykWithText.tif");

Edited by user Tuesday, December 18, 2007 4:50:43 PM(UTC)  | Reason: Not specified

Sincerely yours,
Dmitry Sevostyanov

UserPostedImage Follow Aurigma on Twitter!
camelord  
#3 Posted : Thursday, January 11, 2007 7:58:36 PM(UTC)
camelord

Rank: Member

Groups: Member
Joined: 5/31/2006(UTC)
Posts: 20

OK, lasts a little bit longer, than writing directly on a CMYK Image but it works..

How about setting the Color as CMYK percent values..

like this:

C,M,Y,K are byte values.

Code:
Aurigma.GraphicsMill.CmykColor cmykColor = Aurigma.GraphicsMill.CmykColor.FromCmyk(C,M,Y,K);
            Aurigma.GraphicsMill.Color rgbColor = null;
            Aurigma.GraphicsMill.ColorProfile cmykProfile = new Aurigma.GraphicsMill.ColorProfile(myColorProfilePath);	
            Aurigma.GraphicsMill.Transforms.PixelFormatConverter converter = new Aurigma.GraphicsMill.Transforms.PixelFormatConverter();
            converter.DestinationPixelFormat = Aurigma.GraphicsMill.PixelFormat.Format24bppRgb;
            converter.RgbColorProfile = Aurigma.GraphicsMill.ColorProfile.FromSrgb();
            rgbColor = converter.ConvertColor(cmykColor, cmykProfile);
            return rgbColor;


That works not bad using byte values, but if i need to get an RGB Color defined by percent values, i have a problem.
How can i solve this?
I can't translate e.g. 10% C Color into a byte value..

regards

Christian

Edited by user Tuesday, December 18, 2007 4:51:26 PM(UTC)  | Reason: Not specified

Dmitry  
#4 Posted : Friday, January 12, 2007 3:04:17 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
Hello,

Maximum value of byte is 255 - it is 100%, so 10% of 255 = 255 / 100 * 10% = 25,5. So you can round this value and specify 26.
Sincerely yours,
Dmitry Sevostyanov

UserPostedImage Follow Aurigma on Twitter!
camelord  
#5 Posted : Sunday, January 14, 2007 4:18:56 PM(UTC)
camelord

Rank: Member

Groups: Member
Joined: 5/31/2006(UTC)
Posts: 20

Hi Dmitry,
thanks for the help.

It worked great!

regards
Christian
camelord  
#6 Posted : Monday, January 15, 2007 4:35:58 PM(UTC)
camelord

Rank: Member

Groups: Member
Joined: 5/31/2006(UTC)
Posts: 20

Hi Dmitry,
i have to reroll the Thread..
I found out, that when i use 1 or 2 values like
10,0,0,0 (wich is 26,0,0,0 in Byte)
or 20,70,0,0 (15,179,0,0 in Byte) the DLL translates it correctly. Photoshop shows 10,0,0,0 and 20,70,0,0.

But when i use something like 5,5,90,0 (wich is 13,13,230,0) Photshop shows me 0,0,85,5!!
It looks nearly like the one i wanted, but the Values are very different.
Is this a bug?

here is the Code:

Code:
            string str = "Aurigma"; 
            System.Drawing.SizeF size = System.Drawing.SizeF.Empty; 
            System.Drawing.Font font = new System.Drawing.Font("Arial", 14);
            System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(Aurigma.GraphicsMill.CmykColor.FromCmyk(13, 13, 230, 0));
            Aurigma.GraphicsMill.Bitmap bmp = new Aurigma.GraphicsMill.Bitmap(@"C:\Dokumente und Einstellungen\buettner\Desktop\Test Daten\CMYK_Black.jpg");	
            // Measure string.
            Aurigma.GraphicsMill.Bitmap tempBmp = new Aurigma.GraphicsMill.Bitmap(100, 100,     
                Aurigma.GraphicsMill.PixelFormat.Format24bppRgb);
            System.Drawing.Graphics gdipGraphics = tempBmp.GetGdiplusGraphics();
            try{	
                size = gdipGraphics.MeasureString(str, font);
            }
            finally{	
                gdipGraphics.Dispose();	tempBmp.Dispose();
            }	
            // Create temporary bitmap 32bpp ARGB bitmap and draw string on it.
            Aurigma.GraphicsMill.Bitmap textBitmap = new Aurigma.GraphicsMill.Bitmap(System.Convert.ToInt32(size.Width),     
                System.Convert.ToInt32(size.Height), Aurigma.GraphicsMill.PixelFormat.Format32bppArgb);
            System.Drawing.Bitmap gdipBitmap = textBitmap.ToGdiplusBitmapDirectly();
            gdipGraphics = System.Drawing.Graphics.FromImage(gdipBitmap);
            try{	
                gdipGraphics.DrawString(str, font, brush, 0, 0);
            }
            finally{	
                gdipGraphics.Dispose();	
                gdipBitmap.Dispose();}
                // Convert temporary bitmap with string to CMYK pixel format and draw it on destination bitmap.
            
                textBitmap.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.Cmyk,     
                textBitmap.HasAlpha, textBitmap.IsExtended);textBitmap.Draw(bmp, 20, 20, textBitmap.Width, 
                    textBitmap.Height, Aurigma.GraphicsMill.Transforms.CombineMode.Alpha,     
                    1.0f, Aurigma.GraphicsMill.Transforms.InterpolationMode.LowQuality);
                bmp.Save(@"C:\Dokumente und Einstellungen\buettner\Desktop\Test Daten\CMYK_WithTiff.tif");

regards Christian

Edited by user Tuesday, December 18, 2007 4:52:55 PM(UTC)  | Reason: Not specified

Andrew  
#7 Posted : Wednesday, January 17, 2007 10:15:25 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 876

Thanks: 2 times
Was thanked: 27 time(s) in 27 post(s)
The problem is that CMYK <-> RGB conversion is ambiguous. The same RGB value can be represented with several CMYK values. That's why you never receive exactly same values when convert CMYK -> RGB -> CMYK.

You can reduce the color loss if you will use the color management when converting values color spaces. More detailed information about color management can be found in the documentation. Meanwhile, I have created a code snippet which demonstrates how to use color management in your case:

Code:
            // Load CMYK bitmap
            Aurigma.GraphicsMill.Bitmap bmp = new Aurigma.GraphicsMill.Bitmap(@"T:\ColorConversion\mire_cmyk.jpg");

            // This algorithm assumes that you have CMYK image, and it must have color profile. If 
            // the bitmap does not meet these requirements, we cannot proceed.
            if(bmp.ColorSpace!=Aurigma.GraphicsMill.ColorSpace.Cmyk || bmp.ColorProfile == null)
            {
                throw new ApplicationException("This bitmap is not CMYK or no color profile assigned");
            }

            // Configure PixelFormatConverter to convert the text color value properly. The same converter
            // will be used to convert bitmap with text to CMYK.
            Aurigma.GraphicsMill.Transforms.PixelFormatConverter converter = new Aurigma.GraphicsMill.Transforms.PixelFormatConverter();
            converter.ColorManagementEnabled = true;
            converter.CmykColorProfile = bmp.ColorProfile;
            converter.RgbColorProfile = Aurigma.GraphicsMill.ColorProfile.FromSrgb();

            // Set the text color here color 
            Aurigma.GraphicsMill.CmykColor textColorCmyk = Aurigma.GraphicsMill.CmykColor.FromCmyk(128,12,55,25);

            // Convert the text color to RGB with color management
            converter.DestinationPixelFormat = Aurigma.GraphicsMill.PixelFormat.Format24bppRgb;
            Aurigma.GraphicsMill.RgbColor textColorRgb = (Aurigma.GraphicsMill.RgbColor)converter.ConvertColor(textColorCmyk, converter.CmykColorProfile);
                        
            // Configure text string and font settings
            string str = "TestString";
            Aurigma.GraphicsMill.Drawing.Font font = new Aurigma.GraphicsMill.Drawing.Font("Arial", 24);
            System.Drawing.SizeF size = font.MeasureText(str);
            // Little trick - GDI+ text output is a bit wider, that's why we will tweak the text bitmap width slightly.
            size.Width = size.Width * 1.1f;

            System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(textColorRgb.ToGdiplusColor());

            // Create temporary bitmap for text
            Aurigma.GraphicsMill.Bitmap txtbmp = new Aurigma.GraphicsMill.Bitmap((int)size.Width, (int)size.Height, Aurigma.GraphicsMill.PixelFormat.Format32bppArgb);
            
            // Do not forget to set the same color profile which was used to convert text color from CMYK to RGB.
            txtbmp.ColorProfile = converter.RgbColorProfile;

            // Draw text on the temporary bitmap
            System.Drawing.Graphics g = txtbmp.GetGdiplusGraphics();
            g.DrawString(str,font,brush, new PointF(0,0));

            // Convert the temporary bitmap with text to CMYK. Output color profile must be the same 
            // as the color profile of the main bitmap.
            converter.DestinationPixelFormat = Aurigma.GraphicsMill.PixelFormat.Format40bppAcmyk;
            converter.ApplyTransform(txtbmp);

            // Merge the text with the bitmap.
            txtbmp.Draw(bmp,20,40,-1,-1,Aurigma.GraphicsMill.Transforms.CombineMode.Alpha,1,Aurigma.GraphicsMill.Transforms.InterpolationMode.HighQuality);
            bmp.Save(@"C:\cmyk_with_text.tif");

Edited by user Wednesday, October 29, 2008 2:09:16 PM(UTC)  | Reason: Not specified

Andrew  
#8 Posted : Wednesday, January 17, 2007 10:22:56 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 876

Thanks: 2 times
Was thanked: 27 time(s) in 27 post(s)
If you need the text color to have exact CMYK value, you can use the alternative approach to draw the text. The idea is to create empty ACMYK bitmap filled with the necessary color, and then "cut out" the necessary text in the alpha channel. After that you will just merge this bitmap with the original image.

However this approach has its own shortcomings:

1. You may find the text output quality worse than using the standard approach (not sure though).
2. If the text string is large enough, you will have noticeable memory overhead.

Here is a code snippet demonstrating this:

Code:
            Aurigma.GraphicsMill.Bitmap bmp = new Aurigma.GraphicsMill.Bitmap(@"T:\ColorConversion\mire_cmyk.jpg");

            // Configure text string and font settings
            string str = "TestString";
            Aurigma.GraphicsMill.Drawing.Font font = new Aurigma.GraphicsMill.Drawing.Font("Arial", 24);
            System.Drawing.SizeF size = font.MeasureText(str);

            // Set the text color here color 
            Aurigma.GraphicsMill.CmykColor textColorCmyk = Aurigma.GraphicsMill.CmykColor.FromCmyk(128, 12, 55, 25);

            // Create the solid CMYK bitmap filled with text color and mask where we will "cut out" the text
            // Mask must be 8-bit grayscale bitmap, but if we try to draw anything on such bitmap no antialiasing
            // will be applied. That's why we create 24-bit RGB bitmap and convert it to grayscale later.
            Aurigma.GraphicsMill.Bitmap txtbmp = new Aurigma.GraphicsMill.Bitmap(textColorCmyk, (int)size.Width, (int)size.Height, Aurigma.GraphicsMill.PixelFormat.Format40bppAcmyk);
            Aurigma.GraphicsMill.Bitmap mask = new Aurigma.GraphicsMill.Bitmap((int)size.Width, (int)size.Height, Aurigma.GraphicsMill.PixelFormat.Format24bppRgb);
            
            // "Cut out" the text in the mask
            Aurigma.GraphicsMill.Drawing.GdiGraphics g = mask.GetGdiGraphics();
            font.Antialiased = true;
            g.DrawString(str, font, new Aurigma.GraphicsMill.Drawing.SolidBrush(Aurigma.GraphicsMill.RgbColor.White), new System.Drawing.Point(0,0));
            mask.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.GrayScale, false, false);
            
            // Replace alpha channel by the mask
            txtbmp.Channels[Aurigma.GraphicsMill.ColorChannel.Alpha] = mask;

            // Merge the text with the bitmap.
            txtbmp.Draw(bmp, 20, 40, -1, -1, Aurigma.GraphicsMill.Transforms.CombineMode.Alpha, 1, Aurigma.GraphicsMill.Transforms.InterpolationMode.HighQuality);
            bmp.Save(@"C:\cmyk_with_text.tif");


Hope this helps.

Edited by user Tuesday, December 18, 2007 4:55:09 PM(UTC)  | Reason: Not specified

camelord  
#9 Posted : Monday, February 19, 2007 3:30:28 PM(UTC)
camelord

Rank: Member

Groups: Member
Joined: 5/31/2006(UTC)
Posts: 20

Hi,
because i was on holiday, i write back so late.

Youre second example doesn't work, because
Code:
txtbmp.Draw(bmp, 20, 40, -1, -1, Aurigma.GraphicsMill.Transforms.CombineMode.Copy, 1, Aurigma.GraphicsMill.Transforms.InterpolationMode.HighQuality);

Function throws an unsupported Pixelformat Exception. I use the GraphicsMill (Version 4.0.127.0) DLL. Do you have another one where it works?

I guess, the summary of youre two posts is, that it is not possible to draw a String with any given CMYK Color on a CMYK Image.

If i am right, i ask myself, why does it work e.g. with Photoshop? Even the old Versions (V. 6 from 2001) can write
a Text with any CMYK Color onto a CMYK Image, and the Colors are the ones i wanted.

regards
Christian

Edited by user Tuesday, December 18, 2007 4:55:29 PM(UTC)  | Reason: Not specified

Dmitry  
#10 Posted : Wednesday, February 21, 2007 3:41:23 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
Hello Christian,

Let me answer instead of Andrew.

Adobe can write text on CMYK images because of they implemented their own text renderer for CMYK pixel format.

I have tried this code sample with new version of Graphics Mill for .NET (4.0.127.0). It works...
Sincerely yours,
Dmitry Sevostyanov

UserPostedImage Follow Aurigma on Twitter!
camelord  
#11 Posted : Wednesday, February 21, 2007 6:18:56 PM(UTC)
camelord

Rank: Member

Groups: Member
Joined: 5/31/2006(UTC)
Posts: 20

Hi Dmitry,

i tried it again with another Image as Base Image and it worked! Thx.

Unfortunately, the quality of the text output is, as andrew allready thought, not good. I build this programm to create Images printed on a plastic card, so it has to be good quality.

i also tried to write a text on a rgb image to get the used pixels of the string and replace on the base cmyk image the pixels in two for(..) loops with the setPixel(..) function. This creates a String with exactly the CMYK Colors that i wanted, but
it lasts quiet long with big text strings. So its again not the best solution.

What can i try else?

regards
Christian
Dmitry  
#12 Posted : Thursday, February 22, 2007 12:47:58 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
Hello Christian,

You can try to use direct access to pixel data instead of SetPixel method. It speeds up your application. Please read detailed information in the article "Accessing Pixel Data".

Edited by user Tuesday, October 28, 2008 5:59:09 AM(UTC)  | Reason: Not specified

Sincerely yours,
Dmitry Sevostyanov

UserPostedImage Follow Aurigma on Twitter!
camelord  
#13 Posted : Sunday, February 25, 2007 9:10:30 PM(UTC)
camelord

Rank: Member

Groups: Member
Joined: 5/31/2006(UTC)
Posts: 20

OK, i tried to understand it, but i don't get it :unsure:

Can you post a Codeexample, to detect a RGB.Red Color Pixel in a 24BppPixelFormat Bitmap and overwrite
it with a CMYK(10,20,30,40) Color.
The goal is to find the Pixels, marked with a Color (e.g. Color.Red) and replace them with the CMYK Color, to get a
CMYK Bitmap with exact those Colors..

regards Christian
Dmitry  
#14 Posted : Tuesday, February 27, 2007 7:12:38 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
Hello Christian,

I offer another solution for your task.

Suppose you have 300x300 pixels destination CMYK bitmap. You create 300x300 pixels background CMYK bitmap filled with color that you need for barcode. Than you draw barcode on RGB bitmap using black as background and white as foreground. After that you draw background on destination bitmap using your barcode as mask:

Code:
 // Destination CMYK bitmap 300x300 pixels
Aurigma.GraphicsMill.Bitmap bmp = new Aurigma.GraphicsMill.Bitmap(300, 300, Aurigma.GraphicsMill.PixelFormat.Format32bppCmyk);

// Background - CMYK bitmap 300x300 pixels
Aurigma.GraphicsMill.Bitmap background = new Aurigma.GraphicsMill.Bitmap(@"d:/temp/Background.tif");

// Bar code - RGB bitmap 300x300 pixels
Aurigma.GraphicsMill.Bitmap mask = new Aurigma.GraphicsMill.Bitmap(@"d:/temp/bar.tif");
mask.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.GrayScale, false, false);

// Draw background using bar code as mask
Aurigma.GraphicsMill.Transforms.Combiner combiner = new Aurigma.GraphicsMill.Transforms.Combiner();
combiner.SourceBitmap = background;
combiner.ApplyMaskTransform(bmp, mask);

// Save the result
bmp.Save(@"d:/temp/CMYKBarcode.tif");

Edited by user Tuesday, December 18, 2007 5:31:18 PM(UTC)  | Reason: Not specified

Sincerely yours,
Dmitry Sevostyanov

UserPostedImage Follow Aurigma on Twitter!
Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.