Counting and identifying colours in a vector image using ImageMagick - c#

Customers upload image files, typically logos, to a web site, and I would like to be able to identify which colours the images contain.
I have kindof given up on bitmap images, since the anti aliasing introduces so many variations of each colour, but for vector images (eps, svg, ai to mention a few that could occur) I want to believe it should be doable.
The ideal solution would enable me to produce a list of colours which the user can verify; "Your image contains 3 colours: 111c, 222c and 333c, are these the colours you would like to use for printing?"
I am using Magick.net and C#. I am able to read the files into "MagickImage" instances, but I am lost on how to proceed in identifying the colours.

Let's say you start with this image, which is made from random colours then reduced down to just 18 colours:
convert -size 256x256 xc:black +noise random -colors 18 image.png
Now, you can get a list of the colours like this:
convert image.png -unique-colors -depth 8 txt:
Sample Output
# ImageMagick pixel enumeration: 18,1,65535,srgb
0,0: (7967,24415,7967) #1F5F1F srgb(31,95,31)
1,0: (24415,24672,8481) #5F6021 srgb(95,96,33)
2,0: (16191,12336,16448) #3F3040 srgb(63,48,64)
3,0: (8224,8224,24158) #20205E srgb(32,32,94)
4,0: (24672,24415,24415) #605F5F srgb(96,95,95)
5,0: (49344,16191,16448) #C03F40 srgb(192,63,64)
6,0: (16448,46260,13878) #40B436 srgb(64,180,54)
7,0: (8224,57311,24415) #20DF5F srgb(32,223,95)
8,0: (24415,57568,24415) #5FE05F srgb(95,224,95)
9,0: (49087,49344,16448) #BFC040 srgb(191,192,64)
10,0: (13364,16448,46517) #3440B5 srgb(52,64,181)
11,0: (24415,8224,57311) #5F20DF srgb(95,32,223)
12,0: (24415,24415,57054) #5F5FDE srgb(95,95,222)
13,0: (40863,24672,40863) #9F609F srgb(159,96,159)
14,0: (50372,15163,50115) #C43BC3 srgb(196,59,195)
15,0: (16448,49087,49344) #40BFC0 srgb(64,191,192)
16,0: (41120,40863,41120) #A09FA0 srgb(160,159,160)
17,0: (50372,50372,50372) #C4C4C4 grey77
And maybe you would like a swatch too:
convert image.png -unique-colors -scale 400x40 swatch.png

Related

Byte array or bitmap to svg in c#

How can we convert byte array or bitmap to svg in .net and save the svg file.
Is there any library provided by .net or any third party library which can handle this.
The problem is that Bimap, JPG, PNG, etc. files are raster graphics: they store a fixed array of pixels in various shades of red, green and blue (or hue, lightness and shade - whatever) while SVG files are vector graphics - which means they store images as "draw line from (x1, y1) to (x2, y2)" and "draw an arc here" commands.
And the two are not compatible.
It is possible to do - the process is called "vectorisation" - but the results are unlikely to be perfect, and if you are talking about a natural world object (like a photo of a face) it's very, very unlikely to work without some considerable effort on your part.
read the original article at codeproject.com

Why don't some images show proper Fourier and Inverse spectrums?

I am trying to develop an application for image processing.
Here is my complete code in DotNetFiddle.
I have tested my application with different images from the Internet:
Cameraman is GIF.
Baboon is PNG.
Butterfly is PNG.
Pheasant is JPG.
Butterfly and Pheasant are re-sized to 300x300.
The following two images show correct Fourier and Inverse Fourier spectrum:
The following two images do not show the expected outcome:
What could be the reason?
Are there any problem with the later two images?
Do we need to use images of specific quality to test Image-processing applications?
The code you linked to is a radix-2 FFT implementation which would work for any image with sizes that are exact powers of 2.
Incidentally, the Cameraman image is 256 x 256 (powers of 2) and the Baboon image is 512 x 512 (again powers of 2). The other two images, being resized to 300 x 300 are not powers of 2. After resizing those images to an exact power of 2 (for example 256 or 512), the output of FrequencyPlot for the brightness component of the last two images should look somewhat like the following:
butterfly
pheasant
A common workaround for images of other sizes is to pad the image to sizes that are exact powers of 2. Otherwise, if you must process arbitrary sized images, you should consider other 2D discrete Fourier transform (DFT) algorithms or libraries which will often support sizes that are the product of small primes.
Note that for the purpose of validating your output, you also have option to use the direct DFT formula (though you should not expect the same performance).
I got not time to dig through your code. Like I said in my comments you should focus on the difference between those images.
There is no reason why you should not be able to calculate the FFT of one image and fail for another. Unless you have some problem in your code that can't handle some difference between those images. If you can display them you should be able to process them.
So the first thing that catches my eye is that both images you succeed with have even dimensions while the images your algorithm produces garbage for have at least one odd dimension. I won't look into it any further as from experience I'm pretty confident that this causes your issue.
So befor you do anything else:
Take one of those images that work fine, remove one line or row and see if you get a good result. Then fix your code.

Identify RGB and CMYK in a PDF file

I know this question has been asked before but it doesn't explain much and as I don't have a reputation to comment there I am asking this question.
The answer that was provided in the aforementioned thread retrieves the r g and b values but I don't know what tells if the values that are found show what part is CMYK (as I understand that after rendering all values are converted into RGB).
I need to first identify what color system is used in a pdf file, I understand now that CMYK and RGB can be simultaneously used in a single file. So I need to analyze the pdf file in my C# application and find a way to convert the CMYK parts to RGB if need be.
I learned that conversion can be done using ABCDpdf.
This is a very broad question and it would be better for you if you read at least part of the PDF specification. To give you a taste of why I'm saying this...
PDF and color spaces
1) PDF can contain a wide range of color spaces
- Device color spaces such as RGB, CMYK and Gray
- Abstract color spaces such as Lab
- ICC profile based color spaces such as ICC-based RGB, ICC-based Lab, ...
- Named or special color spaces such as Separation, Device-N and N-Channel
(and I'm omitting some charming ones such as patters and shadings)
2) All of the above color spaces can be used throughout a single PDF file. When your PDF file is compliant to certain ISO standards (such as PDF/A, PDF/X...) it has to obey rules that restrict the number of color spaces, but in general all color spaces are allowed in a single PDF.
3) Where a PDF file is used determines how these color spaces need to be handled. If you want to print to a desktop printer with CMYK inks, something is going to convert all of these color spaces to CMYK. If you're viewing the PDF file on screen, something is going to convert all of these color spaces to RGB.
Converting colors
Yes, you can convert from CMYK (and all of these other color spaces I mentioned) to RGB. But that is also much more difficult that it may sound if you want to do it correctly. As an example have a look at this site: http://www.rapidtables.com/convert/color/cmyk-to-rgb.htm
It contains quick and easy to use formulas for this conversion:
R = 255 × (1-C) × (1-K)
G = 255 × (1-M) × (1-K)
B = 255 × (1-Y) × (1-K)
This will work, but in practice you need an engine (such as for example LittleCMS) that uses ICC Profiles (used to characterise color spaces) to do a proper conversion.

Ghostscript: get CMYK values for rendering from PDF

I need to get the CMYK values used for rendering from the PDF.
I think they are the values range 0 - 1.0 under the C1 key.
Does anyone know how to get them ?
The CMYK values are nothing to do with the 'C1' key. There may be a colorspace defined as /C1, but it will not contain CMYK values.
Any object may be defined in a variety of colour spaces (Gray, RGB, CMYK, sRGB, Separation, DeviceN, NChannel, ICC and some special spaces), for those spaces which are not a device space (ie not Gray, RGB or CMYK) the colour is first converted into one of the device spaces. There are then rules defined in the PDF reference on how the device spaces are converted between themselves.
The actual colour components of an object will be defined in the content stream of the object (for vector objects in a page or Form context) or in the binary data (for images), or calculated from a function (Shading dictionaries).
In order to find any of these you will need to read the PDF file, decompressing streams as required, locate the object you want the information for and then determine the current colour space. Then you can convert the colour components from whatever colour space the object is defined in into CMYK.
Perhaps if you explained what your actual goal is it might be possible to be more helpful.
[UPDATE]
You could simply use Ghostscript to create a new, Grayscale, PDF by setting ColorConversionStrategy=Gray.
This has the advantage of working with all elements of the PDF not only images.
You do realise that a PDF file does not normally consist solely of a raster image ? There can be text, linework, shadings, and transparency groups can also be defined as operating in a given colour space. This is not a simple task.
If you are really only dealing with images then the ColorSpace is defined in the image dictionary (it may be an indirect reference). You will have to parse the PDF file (potentially decompressing it) to find the Color space definition. The sample values for each component are then given by the image data. These will range from 0-65535 (depending on the BPC, 1, 2, 4, 8 or 16 in the image dictionary) and you will have to apply the Decode array to map the values into a range suitable for the colour space.
If you then want to convert to gray scale, then you will have to apply a conversion to Gray. Complex spaces will include a method to map to a device space, and the conversion between device spaces is covered in the PDF reference manual. For ICCBased spaces you will need an ICC colour management engine, you might like to consider LCMS, or you could write your own.

image conversion

I need to convert a RGB (jpg) grayscale CMYK using only to black channel (K).
I'm trying to do this with imageglue, but the result is not what i'm looking for since it converts the grays using the C,M and Y channel and leaves the black channel to 0%.
What I need is if anyone has experience in using any other library/api in .net that could work?
I would start by looking at the ColorConvertedBitmap class in WPF. Here is a link to the docs and a basic example:
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.colorconvertedbitmap(VS.85).aspx
Have you triedAForge.Net?
There is also ImageMagick, a c++ framework for image processing, with a .net wrapper (google for MagickNet)
Her is RGB to/from CMYK question which is related this one:
How is 1-bit bitmap data converted to 8bit (24bpp)?
I found The bitmap transform classes useful when trying to do some image format conversions but ... CYMK is one of the most complicated conversions you can tackle because there is more than one way to represent some colours. In particular equal CYM percentages give you shades of grey which are equivalent to the same percentage of K. Printers often use undercolour removal/transformation which normalises CYMK so that the a large common percentage is taken from CYM and transfered to the K. This is suppose to give purer blacks and grey tones. So even if you have a greyscale image represented using nothing but CYM with a zero black channel it could still print using nothing but K when you get it to a printer using undercolour removal.

Categories