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

Notification

Icon
Error

#gdi-graphics #obsolete

Options
Go to last post Go to first unread
Fedor  
#1 Posted : Friday, February 16, 2007 8:40:00 AM(UTC)
Fedor

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 7/28/2003(UTC)
Posts: 1,545

Thanks: 5 times
Was thanked: 58 time(s) in 57 post(s)
Aurigma.GraphicsMill.Drawing.GdiGraphics does not support CMYK pixel formats, so if you need to draw a text on a CMYK bitmap, you will need to perform some additional actions.

If you attempt to draw text on a bitmap with some of the CMYK pixel formats using the Aurigma.GraphicsMill.Drawing.GdiGraphics class, the following exception will occur:

Code:
Format not supported


The reason to that behavior is that the Aurigma.GraphicsMill.Drawing.GdiGraphics does not support CMYK pixel formats. And when you try to get the GdiGraphics instance to draw a string upon, the error mentioned above occurs.

The avoid this situation, you may do the following:
  1. Draw a text string on a temporary transparent RGB bitmap.
  2. Convert the temporary bitmap to one of the CMYK formats.
  3. Merge the temporary bitmap with the destination bitmap.
This approach is demonstrated below:

Code:
//Configure the text settings.
string str = "Aurigma";
Aurigma.GraphicsMill.Drawing.Font font = new Aurigma.GraphicsMill.Drawing.Font("Arial", 14);
font.Antialiased = true;
System.Drawing.SizeF size = font.MeasureText(str);
System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Red);
Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(@"d:/cmyk32.jpg");

//Create temporary bitmap in 32bpp ARGB bitmap and draw the string on it.
Aurigma.GraphicsMill.Bitmap tempBitmap = new
	Aurigma.GraphicsMill.Bitmap(System.Convert.ToInt32(size.Width),
	System.Convert.ToInt32(size.Height), Aurigma.GraphicsMill.PixelFormat.Format32bppArgb);
System.Drawing.Graphics graphics =
	System.Drawing.Graphics.FromImage(tempBitmap.ToGdiplusBitmapDirectly());
try
{
	graphics.DrawString(str, font, brush, 0, 0);
}
finally
{
	graphics.Dispose();
}

//Convert temporary bitmap with string to the CMYK pixel format and draw it on
//the destination bitmap.
tempBitmap.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.Cmyk,
	tempBitmap.HasAlpha, tempBitmap.IsExtended);
tempBitmap.Draw(bitmap, 20, 20, tempBitmap.Width, tempBitmap.Height,
	Aurigma.GraphicsMill.Transforms.CombineMode.Alpha, 1.0f,
	Aurigma.GraphicsMill.Transforms.InterpolationMode.LowQuality);

bitmap.Save(@"d:/cmyk32-txt.jpg");


Note that in this sample the string is drawn using an RGB color. But what if you want to draw a string using a CMYK color value? In this case you will need to either perform a color conversion (from CMYK to RGB) before drawing the text, or, if you need to keep the exact CMYK value, use a completely different approach to the problem. The idea of this approach is to create an empty ACMYK bitmap filled with the necessary color, and then "cut out" the text in the alpha channel. After that the bitmaps will be merged.

However, this approach has its own shortcomings:
  • You may find the text output quality worse than when using the standard approach (though that is not necessarily so).
  • If the text string is large enough, you will have noticeable memory overhead.
Here is a code sample demonstrating this approach:

Code:
Aurigma.GraphicsMill.Bitmap bmp = new Aurigma.GraphicsMill.Bitmap(@"d:\cmyk32.jpg");

//Configure the text settings.
string str = "Aurigma2";
Aurigma.GraphicsMill.Drawing.Font font = new Aurigma.GraphicsMill.Drawing.Font("Arial", 14);
font.Antialiased = true;
System.Drawing.SizeF size = font.MeasureText(str);

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

//Create a solid CMYK bitmap filled with the text color and a mask where we will
//"cut out" the text. The mask must be an 8-bit grayscale bitmap, but if we try
//to draw anything on such bitmap no antialiasing will be applied. That's why we
//create a 24-bit RGB bitmap and convert it to grayscale later.
Aurigma.GraphicsMill.Bitmap tempBitmap = new Aurigma.GraphicsMill.Bitmap(textColor,
	(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 graphics = mask.GetGdiGraphics();
graphics.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 the alpha channel with the mask.
tempBitmap.Channels[Aurigma.GraphicsMill.ColorChannel.Alpha] = mask;

//Merge the text with the bitmap.
tempBitmap.Draw(bmp, 20, 40, -1, -1, Aurigma.GraphicsMill.Transforms.CombineMode.Alpha,
	1, Aurigma.GraphicsMill.Transforms.InterpolationMode.HighQuality);
bmp.Save(@"d:\cmyk32-txt.jpg");

Edited by moderator Monday, May 28, 2012 8:37:23 PM(UTC)  | Reason: Not specified

Best regards,
Fedor Skvortsov
Tanya  
#2 Posted : Monday, April 28, 2008 4:10:05 PM(UTC)
Tanya

Rank: Advanced Member

Groups: Member
Joined: 5/14/2007(UTC)
Posts: 24

Was thanked: 1 time(s) in 1 post(s)
We glad to introduce you one more approach to draw text on a CMYK bitmap.
This approach was suggested by our customer Brad Erickson. His original post is located here:

The main idea of this approach can be described as follows:
1. Get each color channel from the source CMYK image.
2. Convert each channel to RGB pixel format. That allows us to draw any graphics on the channels using methods of the GdiGraphics class.
3. Draw the text string on each channel with the specified text colors. In other words, if you need to draw a text with (214, 99, 255, 94) CMYK color you should draw this text with (214, 214, 214) color on the Cyan channel, (99, 99, 99) color on the Magenta channel, (255, 255, 255) color on the Yellow channel, and (94, 94, 94) color on the Black channel.
4. Convert each channel back to GrayScale.
5. Put it back into the original CMYK image.

Here is the code sample demonstrating this approach:

VB:
Code:

Dim cmykImageFilname As String = "..\..\Cmyk32.jpg"
Dim resultImageFilename As String = "..\..\result.jpg"

' Load source CMYK bitmap.
Dim cmykBitmap As New Aurigma.GraphicsMill.Bitmap(cmykImageFilname)

' Configure the text settings.
Dim str As String = "Aurigma3"
Dim font As New System.Drawing.Font("Arial", 42)

' Set the text color.
Dim textColor As Aurigma.GraphicsMill.CmykColor = _
    Aurigma.GraphicsMill.CmykColor.FromCmyk(214, 99, 255, 94)

' Get the color channels.
Dim channels As Aurigma.GraphicsMill.ColorChannel() = {Aurigma.GraphicsMill.ColorChannel.Cyan, _
                                                       Aurigma.GraphicsMill.ColorChannel.Magenta, _
                                                       Aurigma.GraphicsMill.ColorChannel.Yellow, _
                                                       Aurigma.GraphicsMill.ColorChannel.Black}


' Get the colors.
Dim colors As Integer() = {textColor.C, textColor.M, textColor.Y, textColor.K}

' Create bitmap for work with each color channel.
Dim colorChannel As Aurigma.GraphicsMill.Bitmap

' Process each color channel.
Dim i As Integer
For i = 0 To 3
    colorChannel = cmykBitmap.Channels(channels(i))

    ' Convert current color channel to RGB, because of GetGdiplusGraphics can work with 
    ' GrayScale bitmaps.
    colorChannel.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.Rgb, False, False)

    ' Get the GDI+ Graphics for the colorChannel and draw the string on it.
    Dim graphics As System.Drawing.Graphics = colorChannel.GetGdiplusGraphics()

    ' Create a solid brush colored with specified RGB color and complete opacity. 
    Dim brush As New System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(255, colors(i), _
        colors(i), colors(i)))

    graphics.DrawString(str, font, brush, 30, 30)

    ' Convert colorChannel form RGB to GrayScale.
    colorChannel.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.GrayScale, False, False)

    ' Put the channel back to the image.
    cmykBitmap.Channels(channels(i)) = colorChannel
Next
cmykBitmap.Save(resultImageFilename)
cmykBitmap.Dispose()


C#:
Code:

string cmykImageFilname = @"..\..\Cmyk32.jpg";
string resultImageFilename = @"..\..\result.jpg";

// Load source CMYK bitmap.
Aurigma.GraphicsMill.Bitmap cmykBitmap = new Aurigma.GraphicsMill.Bitmap(cmykImageFilname);

// Configure the text settings.
string str = "Aurigma3";
System.Drawing.Font font = new System.Drawing.Font("Arial", 42);

// Set the text color.
Aurigma.GraphicsMill.CmykColor textColor =
    Aurigma.GraphicsMill.CmykColor.FromCmyk(214, 99, 255, 94);

// Get the color channels.
Aurigma.GraphicsMill.ColorChannel[] channels = {Aurigma.GraphicsMill.ColorChannel.Cyan,
                                                Aurigma.GraphicsMill.ColorChannel.Magenta,
                                                Aurigma.GraphicsMill.ColorChannel.Yellow,
                                                Aurigma.GraphicsMill.ColorChannel.Black};

// Get the colors.
int[] colors = { textColor.C, textColor.M, textColor.Y, textColor.K };

// Create bitmap for work with each color channel.
Aurigma.GraphicsMill.Bitmap colorChannel;

// Process each color channel.
for (int i = 0; i < 4; i++)
{
    colorChannel = cmykBitmap.Channels[channels[i]];

    // Convert current color channel to RGB, because of GetGdiplusGraphics can work with 
    // GrayScale bitmaps.
    colorChannel.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.Rgb, false, false);

    // Get the GDI+ Graphics for the colorChannel and draw the string on it.
    System.Drawing.Graphics graphics = colorChannel.GetGdiplusGraphics();
    // Create a solid brush colored with specified RGB color and complete opacity. 
    System.Drawing.SolidBrush brush = new 
        System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(255, colors[i], colors[i], colors[i]));
    graphics.DrawString(str, font, brush, 30, 30);

    // Convert colorChannel form RGB to GrayScale.
    colorChannel.ColorManagement.ConvertToContinuous(Aurigma.GraphicsMill.ColorSpace.GrayScale, false, false);

    // Put the channel back to the image.
    cmykBitmap.Channels[channels[i]] = colorChannel;
}

cmykBitmap.Save(resultImageFilename);

Edited by user Monday, April 28, 2008 4:34:25 PM(UTC)  | Reason: Not specified

Best regards,
Tatyana Bertyakova

UserPostedImage Follow Aurigma on Twitter!
Fedor  
#3 Posted : Monday, July 03, 2017 1:24:05 AM(UTC)
Fedor

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 7/28/2003(UTC)
Posts: 1,545

Thanks: 5 times
Was thanked: 58 time(s) in 57 post(s)
Currently, it is possible to draw on CMYK images using the classes of the AdvancedDrawing namespace.
Best regards,
Fedor Skvortsov
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.