![]() |
Color mixer
I'm trying implement this tool:
Code:
I already have this:
http://www.design-lib.com/color_tool_mixer.php
Delphi-Quellcode:
I don't know, don't want to working as expected, F1 :sad:
type
TColorArray = array of TColor; function GetColors(const C1, C2: TColor; Steps: Byte): TColorArray; function Blend(Color1, Color2: TColor; A: Byte): TColor; // by R. M. Klever var c1, c2: LongInt; r, g, b, v1, v2: byte; begin A:= Round(2.55 * A); c1 := ColorToRGB(Color1); c2 := ColorToRGB(Color2); v1:= Byte(c1); v2:= Byte(c2); r:= A * (v1 - v2) shr 8 + v2; v1:= Byte(c1 shr 8); v2:= Byte(c2 shr 8); g:= A * (v1 - v2) shr 8 + v2; v1:= Byte(c1 shr 16); v2:= Byte(c2 shr 16); b:= A * (v1 - v2) shr 8 + v2; Result := (b shl 16) + (g shl 8) + r; end; var V, T: Byte; begin SetLength(Result, 0); V := 100 div (Steps + 1); T := 0; while T < 100 do begin Inc(T, V); SetLength(Result, Length(Result) + 1); Result[High(Result)] := Blend(C1, C2, T); end; end; |
Re: Color mixer
Delphi-Quellcode:
F1 :(
var
V, T: Byte; begin SetLength(Result, 0); V := 100 div (EnsureRange(ASteps, 1, 64) + 1); T := V; while (T < 100) and (100 - T >= V) do begin SetLength(Result, Length(Result) + 1); Result[High(Result)] := BlendColors(AColor1, AColor2, T); Inc(T, V); end; end; |
AW: Color mixer
Unfortunately you forgot to tell us what does happen instead of what should have happened.
And I do not know where you use this function and how you use this function. |
Re: Color mixer
Did you saw link above? So, generaly thera are 2 colors on input and on output I want to array with n colors between input colors - it mean not full gradient, but just n colors.
|
AW: Color mixer
I understood what you want to do but I have no idea what your problem is. Does the code result in a wrong display? Or do you have a problem when you try to use the code? At the moment I am not at home, I will continue there...
|
Re: Color mixer
Maybe my idea is good but imprecise? |
AW: Color mixer
for 100 div (64 + 1) = 1 so you get 100 steps also 100 div (16 +1) = 5 you get 20 steps
Delphi-Quellcode:
var V,T : single; S : byte; V := 100 / (Steps + 1); T := 0; while T < 100 do begin T := T + V; //add real S := trunc(T); //get byte SetLength(Result, Length(Result) + 1); Result[High(Result)] := Blend(C1, C2, S); end; end; |
AW: Color mixer
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
10 Steps on color_tool_mixer.php = 12 with GetColors() (including Color1 and Color2)
uses Math;
(...) function GetColors(const C1, C2: TColor; Steps: Byte): TColorArray; function Blend(const Color1, Color2: TColor; const A: Byte): TColor; // by Aphton var dA : Single; c1 : Array[0..3] of Byte Absolute Color1; c2 : Array[0..3] of Byte Absolute Color2; rs : Array[0..3] of Byte Absolute Result; begin dA := A/100; rs[0] := Round(c1[0] + (c2[0] - c1[0]) * dA); rs[1] := Round(c1[1] + (c2[1] - c1[1]) * dA); rs[2] := Round(c1[2] + (c2[2] - c1[2]) * dA); rs[3] := 0; end; var i: Integer; V, T: Byte; begin if Steps < 3 then Exit; SetLength(Result, Steps); dec(Steps); Result[0] := C1; Result[Steps] := C2; V := 100 div Steps; T := 0; for i := 1 to Steps - 1 do begin inc(T, V); Result[i] := Blend(C1, C2, Min(T, 100)); end; end; Results in... |
AW: Color mixer
Die Sache mit dem
Delphi-Quellcode:
ist unglücklich und führt zu ungenauen Ergebnissen.
V := 100 div Steps;
Wieso nicht einfach eine Mischroutine schreiben, die einen Float-Wert als Mischungsverhältnis akzeptiert (also einfach die von Aphton leicht umschreiben).
Delphi-Quellcode:
Wer komplett auf Floatingpointarithmetik verzichten will, kann es so probieren
function Blend(const Color1, Color2: TColor; const MixRatio: Double): TColor; // by Aphton
var c1 : Array[0..3] of Byte Absolute Color1; c2 : Array[0..3] of Byte Absolute Color2; rs : Array[0..3] of Byte Absolute Result; begin rs[0] := Round(c1[0] + (c2[0] - c1[0]) * MixRatio); rs[1] := Round(c1[1] + (c2[1] - c1[1]) * MixRatio); rs[2] := Round(c1[2] + (c2[2] - c1[2]) * MixRatio); rs[3] := 0; end; ... Delta := 1/Steps; MixRatio := 0; For i:=0 To Steps-1 do begin ColorArray[i] := MixColors(Color1, color2, MixRatio); MixRatio := MixRatio + Delta End;
Delphi-Quellcode:
Die Integer-Variante könnte marginal andere Ergebnisse liefern (sofern sie denn funktioniert).
function Blend(const Color1, Color2: TColor; const MixColor1, MixColor2 : Integer): TColor; // by Aphton
// Mische zwei Farben im Verhältnis MixColor1:MixColor2 var c1 : Array[0..3] of Byte Absolute Color1; c2 : Array[0..3] of Byte Absolute Color2; rs : Array[0..3] of Byte Absolute Result; MixColors : Integer; begin MixColors := MixColor1 + MixColor2; rs[0] := Min(255, (c1[0]*MixColor1 + c2[0]*MixColor2) div MixColors); rs[1] := Min(255, (c1[0]*MixColor1 + c2[0]*MixColor2) div MixColors); rs[2] := Min(255, (c1[0]*MixColor1 + c2[0]*MixColor2) div MixColors); rs[3] := 0; end; ... For i:=1 To Steps-1 do ColorArray[i] := MixColors(Color1, color2, i, Steps - i - 1); |
AW: Color mixer
Ja stimmt, so ist es eig. besser.
Ich habs ja auch nur schnell hingeschrieben, nicht groß überlegt, sry xD |
Re: Color mixer
Liste der Anhänge anzeigen (Anzahl: 1)
Hi, thanks!
Float point version working, but: first element in result is first input color, then steps-1 are real steps. Why? Second int version is making black-white gradient, why? |
AW: Color mixer
There is a small error in the float-version: If you want 3 steps, you need a delta of 0.5 (0->0.5->1.0), so Delta should be 1/(Steps-1);
Delphi-Quellcode:
For question #2 I leave it up to you to find the error yourself (I found it in 5 secs).
Delta := 1/ (Steps-1);
MixRatio := 0; For i:=0 To Steps-1 do begin ColorArray[i] := MixColors(Color1, color2, MixRatio); MixRatio := MixRatio + Delta End; |
Re: Color mixer
Thanks, I tried it too, but I forgot about ( and ) :-D
And what about BW gradient from int version? |
AW: Re: Color mixer
Zitat:
Zitat:
|
Re: Color mixer
Liste der Anhänge anzeigen (Anzahl: 1)
Guys, how to do something similar, but with color wheel, mean not only 2 colors gradient, but N colors beetwen 2 input colors?
|
AW: Color mixer
Are you lazy? Blend Color1->Color2, then Color2->Color3 etc.
|
Re: Color mixer
I don't understand you, what I need to blend with?
|
AW: Color mixer
He means that you simply need to string pairwise blended colors together. That's the common way of doing it, and most probably also the by far easiest, especially if you have gradients for two colors already implemented (since it's the same thing, just done a few times in a row).
|
Re: Color mixer
When I'll blend red and magenta (above image) I'll get RGB(255, 0, 127), this color isn't in example output. So, I still don't understand what I need to blend? :(
|
AW: Color mixer
Ah! You don't want to blend with multiple preset colors in between, but using a different color model I suppose! The above looks like the blending was done in HSV or HSL space. (Don't know if right- or left-handed hue, but that should be simple enough to try out.) So instead of blending using RGB, just do it in HSV/HSL. That should get you pretty close to the above result.
|
Re: Color mixer
RGB(255, 0, 0) = HSL(0, 100, 50)
RGB(255, 0, 255) = HSL(300, 100, 50) add H/S/L values and divide by 2 result HSL(300, 200, 100) = RGB(0, 255, 128) result is similar to color 3 in sample Is this good way? :cyclops: Ah, I don't think so :( |
AW: Color mixer
Well, there is a multitude of possible ways to tweak this. And since we do not know where your sample came from, if you need to reproduce it exactly and how your original reference actually does it, we can merely try and try and try to get closer to it step by step. With only one sample and no way to see what other border colors should produce, this is as far as it gets - at least if we exclude further utter guesswork.
|
Re: Color mixer
So, gradient haven't to be identical as in sample. I just want to know way to get something similar ;) Could you post some example, please?
|
AW: Re: Color mixer
I just saw, that my HSL idea could still work, since you made an error in your example:
RGB(255, 0, 0) = HSL(0, 100, 50) RGB(255, 0, 255) = HSL(300, 100, 50) add H/S/L values and divide by 2 you forgot the latter ;) result HSL(300150, 200100, 10050) = I don't have a converter handy, but I am pretty confident, that this will look a lot more like what you want |
Re: Color mixer
Oh, you've right, thanks ;)
Ok, I'm trying make blender in HSL space and I did it:
Delphi-Quellcode:
This is working. Now 2 questions: this is working in CW mode (as you see on the image posted early), how to make it in CCW? And second one, how to get n colors form this gradient, like in you proposed in RGB mode?
// get both colors HSL values to HSL1 and HSL2
H := Round((MaxHue / 100) * AValue) * (HSL2[0] - HSL1[0]) shr 8 + HSL1[0]; S := Round((MaxSat / 100) * AValue) * (HSL2[1] - HSL1[1]) shr 8 + HSL1[1]; L := Round((MaxLum / 100) * AValue) * (HSL2[2] - HSL1[2]) shr 8 + HSL1[2]; // set result as TColor |
AW: Color mixer
CW or CCW depends a little on how you draw the color circle. The mathematical positive direction is CCW, which also seems to be the common way to draw it. To make it CW, you can just flip the two colors and reverse the generated gradient :)
The multicolor thingy is something quite different: It's for when you want to blend between two colors, but need to define a specific color that should be reached somewhere in the middle of that gradient. Say like you had red->blue, but now you want yellow in there red->yellow->blue. For this you can just make two gradients: red->yellow, yellow->blue, and draw them connected. For the individual gradient parts, you could use whatever gradient method you want, i.e. in RGB or HSL or any other color space of course. This may seem blatant, but to avoid any confusion :) (And at first it seemed like you wanted a gradient with multiple color points defined along the gradient.) |
Re: Color mixer
Liste der Anhänge anzeigen (Anzahl: 1)
CCW I mean something like in attachement (this is in HSB, but idea is identical) ;)
Ok, but problem is, how to get these gradient points? To draw I can use HSL blend function (above; and for example don't use 100 percents, but let's say 4, 8, ... and get 25 colors instead 100) and all will be ok. But I want to get up to 256 colors between 2 colors on HSL wheel (like 256 colors in RGB on begin of this thread) ;) |
AW: Color mixer
Internal color calculation should always be done in floating point, unless for realtime purposes. Usually channels (regardless of the color model) are considered to range from 0 to 1 (exception: YCC, where chroma is -.5 to .5). Only when performing the actual drawing, the float colors are scaled into the target image's color format. That way you would not have the problem, and also minimize quantization errors across the entire application, that are quite prone to emerge when doing multiple and different processes on the same image.
I do not however understand your issue with the (C)CW gradients. CCW -> blend Color1 to Color2. CW -> blend Color2 to Color1, and reverse the resulting list of colors. |
AW: Color mixer
what you call gradient is the result from HSL wheel reduced to 100
if you add the colors and the result goes over 100 what will you get then ? 100 - actual value = new value |
Re: Color mixer
I'm trying and nothing :(
For blend in HSL I have ![]() |
Re: Color mixer
Delphi-Quellcode:
F1 :cry:
var
RGB: array [0..2] of Byte; HSL1, HSL2: array [0..2] of Integer; H, S, L: Integer; begin // get values here // Max* vars are = 256 H := Round((MaxHue / ARange) * AValue) * (HSL2[0] - HSL1[0]) shr 8 + HSL1[0]; S := Round((MaxSat / ARange) * AValue) * (HSL2[1] - HSL1[1]) shr 8 + HSL1[1]; L := Round((MaxLum / ARange) * AValue) * (HSL2[2] - HSL1[2]) shr 8 + HSL1[2]; /// set color here end; SetLength(A, Round(edtSteps.Value) + 2); A[0] := Color1; A[High(A)] := Color2; N := 255 div (Round(edtSteps.Value) + 1); X := 0; Caption := IntToStr(N); for I := 1 to High(A) - 1 do begin Inc(X, N); A[I] := BlendColorsHueCW(Color1, Color2, Byte(X), 255); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz