- BUGS and the like
Sew:Color - rgb colours for various manufactures of coloured embroidery thread.
Extensible Module for determining rgb colours of various manufacturers of embroidering thread and the codes that go with them.
use Sew::Color my @rgb=rgb('Brother', '502'); my $name=name('Brother','502'); print "$name (@rgb)\n"; my @m=manlist();
These calls return respectively the red green and blue components of the colour of the thread and the 'English' name of the thread colour. The colour components will be in the range 0 to 255. In this case, Brother thread number 502. Be aware that the name of the thread colour is not unique, there are some codes that have the same name, although they are mostly different. The above code prints out Mint Green (148 190 140) code(Manufacturer,red,green.blue) This function does a simple search in the colour space to find the colour that is closest to the rgb values you provide. The parameters are Manufacturer: Can be a single manufacturer, a comma seperated list or an array reference of manufacturers. It can be empty to search all known about. red, green, blue are the colour co-ordinates to search for. Distnce is done through a very simple sequential search using a simple 3-d colour model without any weightings. (so rgb all treated the same.) The return values are: In a scalar context, just the code, for example '502'. In an array context it returns a 3 element array, with the following entries Thread code, eg '502' Manufacturer, eg 'Brother' Error distance, eg 42. This is the distance in linear units scaled to 255 between the thread found and the desired colour. Note that it can be more than 255 (Consider that the diagonal of a cube with side 255 is more than 255. ) but will normally not be. Note that only one result is returned, and this ought tobe changed, all nearest results should be found.
The function manlist() returns an array of the names of the manufacturers supported.
If you only have certain threads that you want to search (you dont happen to have the full Madeira in your store cupboard!) you can say which ones you do have by using the custom function. This is called as follows custom('Manufacturer',list of codes, 'Manufacturer', list of codes ) A call to the code function with the special string 'custom' as manufacturer will search only these threads. custom() will reset all the custom threads. Multiple calls to custom where the argument list is not empty will add each new set to the custom search list. The special keyword all may be used with the custom function to either add all the threads for a manufacturer, or to add all threads of all manufacturers. so custom('Brother','all') would add all Brother threads, while custom('all') would add all known threads. Once added individual threads or sets can be removed with the custom_sub function. custom_sub() takes parameters similar to custom and will remove specific threads from the custom search list.
rgb(Manufacturer, code) returns a 255-max scaled rgb tripplet. name(Manufacturer,code) returns the "English" name of the colour. code(Manufacturer-list,r,g,b) returns either the code or an array with the following: (Manufacturer,code,error distance)
All should be aware that giving an rgb value for a thread colour will never be anything more than an approximation at best, even assuming the values are right. Be aware that many thread manufacturers give or sell colour cards that have actual samples of the thread on, because even using paint on paper has proved so unsatisfactory. Really I cannot say it loud enough, trying to represent real-world colours that are not a photograph, using rgb values is massively approximate at best. For example, it depends on the angle of the light, the amount of light, the type of light and other factors. Or it may not. I have seen materials that change colour quite noticibly depending on weather they are viewed by sunlight, incandescent light or flourscent light. Its a manufacturers nightmare, but it happens.
In the main these values were derived by me by taking a web page which has a photograph of the thread, cropping it to remove anything like a shadow, changing the size to 1 by 1 pixcel (so that all other pixcels are averaged) and then listing the colour of that pixcel. This results in rather real-world values - the extreme ends of the scale near 0 and 255 do not appear and the colours are a bit less saturated than... well then you might think. Sulky helpfully provide a spreadsheet with rgb values. It would be a bit silly not to use it, wouldnt it? But the truth is that the values you get are very different since they have clearly been normalised in some way so that blacks are fully black and whites are fully white. For example, Sulky "Black" 942-1005 has rgb values (0,0,0) in the spreadsheet. But using the other method, has rgb values (44,42,44). Which is right? The answer is of course that both are, and you need to use the values obtained carefully and sensibly, processing them if needed. Sulky do this (perhaps) because in part you are throwing away some of the precision in your 8 bit representation if you say the lowest value I am going to have is 42. They are (probably) not happy using 8 bits any way, because from there perspective this is not much precision to represent a world of colour, why throw some of it away? Which Sulky values did I include? In the end I included the real-world values since thats more compatible with the other manufacturers in the package. Let me know if you think I should do other wise. It also allows me to easily include varigated threads (that have a delibneratly variable colour along its length) since this will be correctly averaged.
The module may be extended to a new manufacturer by adding lines of the following format to the module:
for example the line Brother,Moss Green,515,48,125,38
is responsible for the Moss Green number 515 entry.
There are many manufacturers not covered. If you use this please drop me an email to say it has been useful (or not) to you. The sat() function generally returned 255 in version 1.04. This is fixed in 1.05
Mark Winder June 2012. markwin (at) cpan.org