PDA

View Full Version : کد برای رنگ کردن بیت مپ با ته رنگ مشخص



mbshareat
دوشنبه 25 اردیبهشت 1391, 11:39 صبح
سلام
من خیلی پیش تو این تاپیک (http://barnamenevis.org/showthread.php?230670-Colorize-%D8%AF%D8%B1-%D8%AF%D9%84%D9%81%DB%8C%D8%9F!&highlight=Colorize) در مورد رنگی کردن بیت مپ پرسیدم. جناب SAASTN لطف فرمودند چیزی مثل Hue/Saturation فتوشاپ برام گذاشتند.
من یه کد می خوام برای رنگ کردن بیت مپ با یک ته رنگ (Tint) مشخص
اگه با فلش کار کرده باشید حتما می دونین که میشه برای یک Movie ته رنگ تعیین کرد که ظاهرا با رنگ کلیپ ترکیب می کنه که خواسته من نیست.
اما من می خوام چیزی مثل GrayScale و Sepia ولی با رنگ مشخص داشته باشم.
می خوام یه پروسیجر باشه که بهش رنگ رو بدم و بیت مپ رو به اون رنگ در بیاره نه اینکه HUE رو بهش بدم.
اگه کسی کد سر راستی داره لطفا بذاره.
ممکنه این کد رو تو کامپوننتم استفاده کنم. بنابر این لطفا کامپوننت معرفی نکنین...ممنون!

SAASTN
دوشنبه 25 اردیبهشت 1391, 22:32 عصر
نمی دونم درست متوجه شدم یا نه. ولی شما می تونی با GraphUtil.ColorRGBToHLS رنگ مد نظر رو تبدیل به ورودی مناسب برای همون کد بکنی. اگه منظورت چیز دیگه ایه یکم بیشتر توضیح بده.

mbshareat
سه شنبه 26 اردیبهشت 1391, 00:14 صبح
سلام
من یه دکمه روی فرم گذاشتم و کد زیر رو امتحان کردم به نتیجه نرسیدم.نه با تیک Colorize نه بدونش!
procedure TForm1.Button1Click(Sender: TObject);
Var
H,L,S:Word;
begin
ColorRGBToHLS($F00F80,H,L,S);
SetBitmapHLS(ImageSource.Picture.Bitmap, ImageDest.Picture.Bitmap,
H, L, S);
end;

SAASTN
سه شنبه 26 اردیبهشت 1391, 01:52 صبح
آقا محمد دقت نکردیا! بجای SetBitmapHLS باید از ColorizeBitmap استفاده می کردی. هر چند طبق بررسی های اخیر اون تابع یکم آچارکشی احتیاج داشت!:لبخند:
procedure ColorizeBitmap(const Source, Dest: TBitmap; const H, L, S: Word);
var
I: Integer;
J: Integer;
SP, DP: PByteArray;
Color: TColor;
ColorValue: Double;
begin
for I := 0 to Source.Height - 1 do
begin
SP := Source.ScanLine[I];
DP := Dest.ScanLine[I];
for J := 0 to Source.Width - 1 do
begin
ColorValue :=
SP^[J * 3 + 0] * 0.11 + SP^[J * 3 + 1] * 0.59 + SP^[J * 3 + 2] * 0.3;
Color := ColorHLSToRGB(H, (Round((ColorValue))+L)div 2, S);
DP^[J * 3 + 0] := GetBValue(Color);
DP^[J * 3 + 1] := GetGValue(Color);
DP^[J * 3 + 2] := GetRValue(Color);
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
Var
H,L,S:Word;
Color: TColor;
begin
if ColorDialog1.Execute then
begin
ColorRGBToHLS(ColorDialog1.Color,H,L,S);
ColorizeBitmap(ImageSource.Picture.Bitmap, ImageDest.Picture.Bitmap,
H, L, S);
Shape1.Brush.Color := ColorDialog1.Color;
ImageDest.Repaint;
end;
end;

اگر هم می خوای تاثیر شدت نور رنگ انتخابیت بیشتر بشه می تونی مثلا به این روش عمل کنی:
Color := ColorHLSToRGB(H, (Round((ColorValue))+ 3 * L) div 4, S);

اما هر چی این تاثیر رو بیشتر کنی کنتراست تصویر خروجی کمتر می شه.

mbshareat
سه شنبه 26 اردیبهشت 1391, 09:36 صبح
سلام
واقعا ممنونم. من تو اینترنت گشتم چیز بدرد بخوری پیدا نکردم.نمی دونم شما این کدها رو خودتون می نویسین یا از جایی گیر میارین.در هر صورت گل کاشتین.
راستش اسم من محمد باقر شرعیّات (احکام شرعی!!) هستش.

mbshareat
سه شنبه 26 اردیبهشت 1391, 10:40 صبح
سلام
من محمد باقر شرعیات هستم!
بهتره Color رو هنگام تنظیم ته رنگ اینطور حساب کنیم:
Color := ColorHLSToRGB(H, Round(ColorValue),S);
فایدش اینه که اگه تو بیت مپ رنگ سفید داشته باشین همون سفید می مونه!
این هم برنامه اصلاح شده خودتون:

راستش من هنوز درست نفهمیدم اشباع چیه و چه ضرورتی داره و چه فرقی از نظر تنظیم RGB با Luminance و کنتراست و گاما و Brightness داره!
به ما گفتند اشباع یعنی تنظیم میزان خاکستریه و کنتراست یعنی تباین رنگ (که مثلا اختلاف شدت سایه روشن و تیره زیاد و کم بشه).
فکر می کنم روشنایی (Luminance) یعنی تنظیم RGB با حفظ تناسب مقادیر در صورت کاهش و با حفظ تناسب فاصله مقادیر از 255 در صورت افزایش؟!

SAASTN
سه شنبه 26 اردیبهشت 1391, 11:09 صبح
بهتره Color رو اینطور حساب کنیم:
من مطمئن نیستم که آیا استاندارد دقیقی برای این کار وجود داره یا نه، فکر کنم قضیه یخورده تجربی باشه و شما باید ببینی چی تو کار خودت بهتر جواب میده. اما این تغییری که ایجاد کردی باعث میشه شدت نوری رنگ انتخابی هیچ تاثیری توی خروجی نداشته باشه. یعنی اگه شما یه زرد خیلی روشن یا یه زرد خیلی تیره رو بفرستی میبینی که روشنی تصویر خروجی تغییری نمی کنه. البته همونطور که گفتم این لزوما اشکال نیست و شما باید برا کار خودت جواب بگیری.

راستش من هنوز درست نفهمیدم اشباع چیه و چه ضرورتی داره و چه فرقی از نظر تنظیم RGB با Luminance و کنتراست و گاما و Brightness داره!
بهترین روش برای این که اینا رو بشناسی اینه که بری تو فتوشاپ تو پنجره انتخاب رنگش اون مقادیر رو تغییر بدی ببینی رنگ چه تغییری می کنه. ولی شما هرچی Saturation یا همون اشباع رو کم کنی رنگت کدر تر و خاکستری تر میشه و هر چی زیادش کنی رنگت شفاف تر و زنده تر میشه. به عنوان مثال clRed و clLime حداکثر اشباع رو دارن در صورتی که clGray و clSilver حداقل اشباع رو. به این نکته هم توجه کن که توی فضای رنگی HSB یا همون HLS وقتی S تغییر کنه نه رنگ تغییر می کنه(مثلا اگه قبلا سبز بوده بازم سبز می مونه) نه شدت نوری اون. بازم می گم، برو تو فتوشاپ یه ذره با این مقادیر ور برو متوجه میشی. فقط B اونجا معادل L اینجاست.

mbshareat
سه شنبه 26 اردیبهشت 1391, 14:08 عصر
سلام و درود
قبل از این که شما بفرمایین فهمیده بودم که رنگ FF$ با F$ فرقی در نتیجه نداره.
بعد از کلی حواس پرتی به این کد رسیدم:

procedure SetBitmapTint(const Source, Dest: TBitmap; const C:TColor);
Var
H,MainL,L,S:Word;
I: Integer;
J,Delta: Integer;
SP, DP: PByteArray;
Color: TColor;
ColorValue: Double;
begin
ColorRGBToHLS(C,H,MainL,S);
for I := 0 to Source.Height - 1 do
begin
SP := Source.ScanLine[I];
DP := Dest.ScanLine[I];
for J := 0 to Source.Width - 1 do
begin
ColorValue :=
SP^[J * 3 + 0] * 0.11 + SP^[J * 3 + 1] * 0.59 + SP^[J * 3 + 2] * 0.3;
Delta:=Round(ColorValue-120);
If Delta>0 Then
L:=MainL+Round((240-MainL)*(Delta/127))
Else
L:=MainL-Round(MainL*(Delta/128));
Color := ColorHLSToRGB(H, L, S);
DP^[J * 3 + 0] := GetBValue(Color);
DP^[J * 3 + 1] := GetGValue(Color);
DP^[J * 3 + 2] := GetRValue(Color);
end;
end;
end;


اما نمی دونم چرا در بعضی رنگها مثل FF80FF$ خوب کار نمی کنه!

mbshareat
سه شنبه 26 اردیبهشت 1391, 20:57 عصر
سلام
اینجای کد رو درست کنین:

Else
L:=MainL+Round(MainL*(Delta/128));