From: Robert L K. <rl...@al...> - 2000-04-30 00:46:05
|
Date: Sun, 30 Apr 2000 01:19:31 +0200 From: Thomas Tonino <tt...@bi...> Robert L Krawitz wrote: I think there is a problem in semantics with CMYK color. There are 4 values to control what is essentially a 3 dimensional color space. If I ignore this, the code seems to do the following: 1 - Finds how dark the requested CMY values are - but not the requested K value (tk). Well, the problem is that we're being handed RGB, so we don't really have a "requested" K value; we have to compute one. There's a whole bunch of code in there that I don't entirely understand; the stuff that adjusts the K value. Or rather, I think I understand in a general sense what it does, but I don't entirely understand how it interacts with my later handling of black. I tried ripping it out the other night, and the results weren't too good. I do want to figure out what's going on in there. 2 - Finds what is more black: the requested K or the value computed above (not sure about this, this would bite us if people feed color separated data with its own black curve to us). Yes, it would. Currently we don't support CMY or CMYK input, though. 3 - We find where this black level is in the range between the upper and lower settings mentioned above. 4 - If below, print the CMY values. If above, print black. If in between, use a dither to determine whether black will be used or CMY. Almost right. If it decides not to use black, the black is redistributed back to the CMY. Am I missing something if I think we could just generate black according to steps 1, 2 and 3 and put this black value in the K buffer - and have the actual rendering dither decide where black must be printed? Where this dither prints black, CMY do not show up. I do not see what the extra dither here gains us. But I see a possible problem: it may decide not to print CMY at a certain pixel. Then the final dither comes along, finds no CMY and thus prints no CMY, but if it also does not have enough error yet for printing K, it leaves a hole - giving reduced density where CMY moves into black. What the extra dither does is eliminate all printing of black in light areas, which makes for a much smoother texture (try setting k_upper and k_lower to zero and see what happens...you won't like it. It's even worse on a 6-color printer.) Actually, step 1 seems a bit strange to me. It looks like a darkness is computed by adding densities. In offset printing, the color is analyzed in a different way. As first approximation, we would take the lowest of CMY and use that as a K value. Adding CMY is bad when printing saturated colors: for say a dark blue (which is magenta and red, and some yellow to make it real dark) the driver would decide that part of the CMY can be replaced with K because it is so dark - but it really should not replace more CMY than there is Y to replace. I thought about this some more. The way darkness is computed is strange, but we're computing "darkness", not "black", here. That's important -- pure C has a certain amount of "darkness", even though there's no black whatsoever. The idea is to avoid using black ink when the darkness is not great enough to hide the solid black speckles. Darkness is not K; it's used to decide how we're going to print K. There's a difference. If we print K as CMY, we don't simply print a C, M, and Y dot; the K->CMY values are added back into the CMY and normal dithering takes place on the CMY values. I still don't think that the way darkness is computed is optimal, though. It really needs more careful thought. The dither algorithm will then produce a K every now and then. When the K is produced, and at the same time a CM or Y would be printed, this dot is not shown - but for the error diffusion it works out as if it is - the color effectively disappears under the black dot. You have to rely on printer registration here - or you have to make the switch around 30% coverage, when there is often white between dots and misalignment doesn't matter that much. On most paper, at least, dots are not simple square or rectangular pixels; they spread out and overlap somewhat. That's why we don't want a target density of 1.0, but instead something less (about .6 for most Epson printers at 720 dpi; half that at 1440 dpi). At 360 dpi, though, where individual dots are more visible, this might matter. I haven't investigated it. In offset printing it is normal to leave color behind black ink. In some cases, colors are boosted a bit when there is a lot of black - so a shadow in a colored object still feels black. Given that our dither takes care of the total amount of ink buildup, I feel it is better to just adjust the amount of black and let the dither handle the rest. With the above, we cannot get above 200 % - unless we believe it is not a good idea to remove all color from under black. Dark saturated colors will then get a 300% coverage. Maybe we need another mechanism to adjust those: not by shifting them to black, but by making them lighter overall. We don't want more than 200% coverage. In fact, I don't think we even *want* 200% coverage. It's simply too much ink, and aside from the expense, it will bleed through uncoated paper. I just tried patching the code but now I get only an abrupt transition from greenish (CMY) to grey (K). Guess I'm a stupid coder or the black dither is not behaving as I expected. What I did was use this in print-dither.c instead of the dither lookup function. Be warned, it is useless, but shows my plan: else if (kdarkness < ub) /* Probabilistic */ { if (rb == 0) bk = ok; else bk = ok * ( (kdarkness - lb) / rb ); } else /* All black */ I tried this too a while back, and it definitely doesn't work very well. It might work with ordered dither, but it's not useful with error diffusion. In fact, the interaction between error diffusion and this dither might be the source of some problems. This doesn't really matter for the point I was trying to make. Say === is black formed by CMY and K is black formed by black ink. The layers could add as follows: === === === === === === === === === === === === K K K K K K K K K K K K K K K K K K K K K K K K In this case - and this is a very ordered dither - the black does not make the CMY any darker. CMY would not print where black is printed (nice idea - but hey, are black and CMY perfectly in registration?) but still 25 % of the paper will be white - even though you did add 50% black to the 75% grey that you had. I don't know about offset printing, but in this context, the black very definitely makes CMY look darker. Pure CMY (from ink jet printers, at any rate) is not very black. Black, on the other hand, completely hides anything else printed on that spot. Also, with what you presented above, 25% of the paper will not be white at all; this pattern will result in a fully covered paper, and in fact the bleed-through will be heavy if the paper is not coated, and if it is, there will probably be heavy pooling of ink. Think dot gain in this context. Or something similar. That is, after the fixed dither an ink removal algorithm removes pixels that do not add to the image, but just soak the paper. Ink removal might be a good thing to investigate; we just have to figure out what can be safely removed. BTW, what 1440 buys us is mostly more points for the dither algorithm to work with. It doesn't really buy us more resolution on paper, since the dots are too big. The 1440x1440 and 2880x720 pseudo-resolutions attempt to do the same thing to an even greater degree. -- Robert Krawitz <rl...@al...> http://www.tiac.net/users/rlk/ Tall Clubs International -- http://www.tall.org/ or 1-888-IM-TALL-2 Member of the League for Programming Freedom -- mail lp...@uu... Project lead for The Gimp Print -- http://gimp-print.sourceforge.net "Linux doesn't dictate how I work, I dictate how Linux works." --Eric Crampton |