Using CMYK colours in WPF/XAML - wpf

Is there any way to specify CMYK colours directly in a XAML document?
prefixing them with # character will create RGB colours, but how to specify a CMYK colour?
Some notes:
The question is NOT about converting from CMYK to RGB but to use real CMYK
The purpose is to allow generated XPS documents (using System.Windows.Xps.Packaging for example) see the colour as CMYK and generate colour codes as "ContextColor /swopcmykprofile.icc a,b,c,d,e" not as "#aarrggbb"
I have tried to define CMYK colours by using ColorContext without any success.

OK again!
It turned out to be much more easier than what I though:
CMYK is directly usable in XAML:
<Grid Background="ContextColor file://C:/WINDOWS/system32/spool/drivers/color/EuroscaleCoated.icc 1.0,0.0,0.0,1.0,1.0">

OK! I found the answer:
The way that WPF uses colour models is by System.Windows.Media.Color's static constructor FromValues() and introducing a colour profile:
The following code, for example:
var c = Color.FromValues(
new float[] {1.0f,0.0f,0.0f,0.0f } ,
new Uri("file://C:/ICCProfile.icc", UriKind.Absolute));
creates a 100% Cyan colour.
Profiles can be downloaded from http://www.eci.org/doku.php?id=en:start
I tested this solution with XpsDocumentWriter and I confirm that it creates the correct CMYK colour code.
For XAML it is just the matter of building an IValueConverter that converts something like "~C,M,Y,K" (as #RRGGBB for RGB) to a real CMYK colour.

Related

How to create pie chart using wpftoolkit with shades of only one colour

I am new to wpf, I am using wpf toolkit to create pie chart. I have created pie chart using wpf toolkit but my problem is that I have to create Pie chart only with a particular color shade. Say for example green, then my pie chart should use shades of green only. Also this assignment of color to pie pieces should be done pro grammatically.
Can anyone please advice how I go about it?
There isn't a simple answer to your question.
You can set the colors manually, or let the framework pick random ones for you.
What you could do, is have a method that takes as an argument the amount of series in your graph, and a color, and returns an array of colors of that color shade.
You'll have to look at how colors work (RGB) and figure out how you want to do that (keep in mind if you have heaps of series, this will not look good).
Have a look at this colorpicker page for a quick understanding of what you're looking for (in shades).
an example going from dark blue to white will have the following values:
#000000
#00001A
#000033
#00004C
#000066
#000080
#000099
#0000B2
#0000CC
#0000E6
#0000FF
#1919FF
#3333FF
#4D4DFF
#6666FF
#8080FF
#9999FF
#B2B2FF
#CCCCFF
#E6E6FF
#FFFFFF
and it shouldn't be hard to pick from that array 4 shades for example.
Then you'll have to manually (well, with a for loop, but still, in code) add them to your series.
You can use below code in order to change the shades of the charts.
if you want to change from XAML then use this code:
<chartingToolkit:PieSeries x:Name="piecharts"
ItemsSource="{Binding DepartmentwiseGroupedEmployee}"
IndependentValuePath="DeptName"
DependentValuePath="DeptId">
<chartingToolkit:PieSeries.Effect>
<DropShadowEffect ShadowDepth="10" BlurRadius="14" Color="Green"/>
</chartingToolkit:PieSeries.Effect>
</chartingToolkit:PieSeries>
or if you want to change from code then use below code:
var shadowEffect = new DropShadowEffect();
shadowEffect.Color = Colors.Green;
shadowEffect.ShadowDepth = 10;
shadowEffect.BlurRadius = 14;
piecharts.Effect = shadowEffect;

FormatConvertedBitmap poor Black and White results

This seems to be the standard method to convert the pixel format of a bitmap but it's giving me a very poor result when converting to black and white format:
// convert to black & white bitmap
FormatConvertedBitmap monoBitmap = new FormatConvertedBitmap(bitmap, PixelFormats.BlackWhite, null, 0);
// save black & white bitmap to file
fileName = string.Format("{0}.bmp", data.SelectedProduct.Code);
bitmapEncoder = new BmpBitmapEncoder();
bitmapEncoder.Frames.Add(BitmapFrame.Create(monoBitmap));
using (Stream stream = File.Create(fileName))
{
bitmapEncoder.Save(stream);
}
The resulting image file is very grainy and pixelated. I need to send it to a line printer so I need sharp edges.
The original before conversion looks fine (its 32BPP color) and if I use something like IrfanView to manually convert the original to black and white it also comes out much better than whatever .NET is doing.
Is there another alternative for doing this in .NET instead of FormatConvertedBitmap?
It are using PixelFormats.BlackWhite, which uses only black and white colors in the resulting image, which probably can make it look grainy if there are light pixels surrounded by darker ones. I suppose the effect can be better, if you convert the image to use the shades of gray. In order to do this, you this line of code instead of the one in the code you've posted:
FormatConvertedBitmap monoBitmap = new FormatConvertedBitmap(bitmap, PixelFormats.Gray32Float, null, 0);
This should convert the image to use only only shades of gray, so no color will be needed to print it.
Let me know if it's the effect you want to achieve.
You can find some more information about PixelFormats class here: http://msdn.microsoft.com/en-us/library/system.windows.media.pixelformats.aspx.

How can I render a monochrome bitmap in color in WPF?

Back in Win32 days, if I had a monochromatic bitmap, which is for all intents and purposes just a bitmap mask, I could render that bitmap onto a DeviceContext. What would happen is every pixel where there was a '0' it rendered as transparent, and every pixel where there was a '1' it rendered in the currently selected forecolor. This was very handy.
However, after a few weeks of searching, I haven't seen anything similar in WPF.
Now I was about to just roll my own MonochromeBitmapImage class, but thought if anyone would know another way to do this, it would be you all, the S.O. users, so there's my question... how, in WPF, can I render a monochrome bitmap with one value being a specificed color and the other value being transparent?
A pretty similar feature is OpacityMask for UIElement. It will display the parts that isn't transparent in the OpacityMask. It can be used with
Brushes - SolidColorBrush etc
Visuals - VisualBrush
Images - ImageBrush
etc
Here is an example with a Button using an ImageBrush
<Button Content="Opacity Mask">
<Button.OpacityMask>
<ImageBrush ImageSource="C:\OpacityRect.png"/>
</Button.OpacityMask>
</Button>
It depends if you need to use monochrome bitmaps or you just want to be able to recolor the image. If you can use any image format I would use png with alpha then you can use the image as an OpacityMask, no code necessary. By using the image as an OpacityMask you can easily change the colour, use a gradient or an ImageBrush.
<Rectangle Fill="Blue">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="..." />
</Rectangle.OpacityMask>
</Rectangle>
If you need to use 1-bit bitmaps it's quite simple to convert them to an indexed format with a custom palette. You could set the colour you want in the palette or just choose anything and use it as an OpacityMask. FormatConvertedBitmap seems to need a different format just a different palette had no effect.
public static FormatConvertedBitmap Recolor(BitmapImage b, Color c)
{
return new FormatConvertedBitmap(b, PixelFormats.Indexed2, new BitmapPalette(new List<Color>() { Colors.Transparent, c }), 0);
}
Another option would be a PixelShader it's a bit overkill for this kind of thing but for more complex manipulations they useful.

CMYK to RGB formula of Photoshop

Is there a place where I can get the formula which photoshop uses to convert rgb to cmyk?
I know there are formulas on the web, but photoshop does not use this formula. It converts the collors different.
Can someone tell me the photoshop formula?
Thanks!
Most likely, Photoshop uses a color profile for converting RGB to CMYK.
If you want to do the same with a .NET language on Windows, then there's an API for it:
float[] colorValues = new float[4];
colorValues[0] = c / 255f;
colorValues[1] = m / 255f;
colorValues[2] = y / 255f;
colorValues[3] = k / 255f;
System.Windows.Media.Color color = Color.FromValues(colorValues,
new Uri(#"C:\Users\me\Documents\ISOcoated_v2_300_eci.icc"));
System.Drawing.Color rgbColor = System.Drawing.Color.FromArgb(color.R, color.G, color.B);
Note that two different Color classes from two different namespaces are used. And you probably need to add the PresentationCore DLL as a reference.
In this particular case, the ISO Coated v2 300% (ECI) profile is used. It can be downloaded from the downloads section of eci.org. It's part of a bigger ZIP file containing several profiles.
If you need to convert a complete image from CMYK to RGB, there are special classes in the same namespace that use a color profile as well.
There's a nice little online app for testing the CMYK color conversion with a color profile.
They are many different ICC Color Profiles for storing color as CMYK and RGB. There is no one end all be all encoding for color. There is RGB, sRGB, Adobe RGB, U.S. Web Coated (SWOP) v2, GRACol, etc.
As a print provider I'd ask what your end goal is. We can talk a bit about Photoshop scripting if you are looking to work with color objects in Adobe Javascript, but if this has to do with design I would lend this caution:
The RGB color space provides a wider color gamut (more colors), many photoshop effects are only available while working in RGB, and the RGB filesize is smaller (only storing 3 channels RGB, instead of 4 CMY & K).
If you save a document as CMYK when it goes to the printer device the printer hardware reinterprets the colors anyhow. So it does not benefit you to work in CMYK most of the time.
I do use PhotoShop, but a google search tells me that this varies by the devices you are using, and is controlled in Edit > Color Settings (Shift+Ctrl+K).

UIElement to PNG - Text slightly blurred

I am using ImageTool's PNG encoder to create an image.
I have a Grid that contains multiple TextBlocks, each TextBlock contains dynamic text.
When I create a WriteableBitmap from the grid containing the TextBlocks, I then use ImageTool's encoder to convert the WriteableBitmap to a PNG image.
All works well, however, when I view the PNG image (am saving the file to the hard drive for testing purposes) - the text looks slightly blurred. Is this an issue with the encoder or the WriteableBitmap class? And - has anyone experienced this before and are there workarounds?
Thanks.
I'm a part of ImageTool project but I'm playing as a tester since I'm using this library in one of my project... If you can create a sample then you can probably show us so that we can test in our machine.
You can also try with Joe Stegman's encoder or fJCore JPEG encoder.

Resources