گه احتمالا تاحالا سعی کرده باشید که یه برنامه دیتابیس بنویسید به مشکل تاریخ شمسی بر خوردید!!!
دیتابیسها از تاریخ میلادی پشتیبانی میکنن و از تاریخ شمسی ما بدشون میاد !!!
توابع تبدیلی رو نت میشه پیدا کرد مثلا یکی تو سایت www.iranasp.net معرفی شده که شدیدا تو سالهای کبیسه باگ و قاط داره.
تقریبا تمام کسانی که از روشهایی مبتنی بر یکسری آرایه برای محاسبه استفاده کردند دچار مشکل هستن و اصلا قابل اعتماد نیستن. اما روشی که من میخوام معرفی کنم کاملا علمی و بر پایه محاسبات علم نجوم و تقویم شناسی پیاده سازی شده و اصلا مو لا درزش نمیره!!(میگی نه تستش کن)
اما یه نکته که هست اینه که چون من کارهای دیتابیس رو با Delphi انجام میدم اینو بصورت 2 تا تابع دلفی نوشتم و چون نیازی به استفاده تو ویژوال سی نداشتم به سی تاحالا ننوشتم و اگه فرصت شد و خواستید مینویسم و تو وب لاگ میگذارم.
2 تا تابع یکی برای تبدیل میلادی به شمسی و دیگری برای تبدیل شمسی به میلادی هستش و خروجی اینها رو من یه رشته در نظر گرفتم ::
function Miladi2Shamsi(iyear,imonth,iday:integer):string;
var
aa:string ;
jdn,jdn2,depoch,cycle,cyear,ycycle,aux1, aux2,yday:integer;
epbase,epyear,mdays:integer;
Const PERSIAN_EPOCH = 1948321 ;
begin
If ((iYear > 1582) Or ((iYear = 1582) And (iMonth > 10)) Or ((iYear = 1582) And (iMonth = 10) And (iDay > 14))) Then
jdn:=((1461*(iYear+4800+((iMonth-14) div 12))) div 4)+((367*(iMonth-2-12*(((iMonth-14) div 12)))) div 12)-((3*(((iYear+4900+((iMonth-14) div 12)) div 100))) div 4)+iDay-32075
Else
jdn := 367 * iYear - ((7 * (iYear + 5001 + ((iMonth - 9) div 7))) div 4) + ((275 * iMonth) div 9) + iDay + 1729777;
epbase:=475-474;
epyear:= 474 + (epbase Mod 2820) ;
mdays:= (1 - 1) * 31 ;
jdn2:=1+mdays+ Trunc(((epyear*682)-110)/ 2816)+(epyear-1)*365+Trunc(epbase / 2820)*1029983+(PERSIAN_EPOCH-1);
depoch:=jdn-jdn2;
cycle:= Trunc(depoch / 1029983);
cyear:= depoch Mod 1029983 ;
If cyear = 1029982 Then
ycycle:=2820
Else
begin
aux1:=Trunc(cyear / 366);
aux2:=cyear Mod 366;
ycycle:=round(((2134*aux1)+(2816*aux2)+2815) / 1028522)+aux1+1;
End;
iYear:=ycycle+(2820*cycle)+474;
If iYear <= 0 Then
iYear:=iYear-1;
If iYear>=0 Then
epbase:=iYear-474
Else
epbase:=iYear-473;
epyear:=474+(epbase Mod 2820);
mdays:=(1-1)*31;
jdn2:=1+mdays+Trunc(((epyear*682)-110)/ 2816)+(epyear-1)*365 +Trunc(epbase / 2820)*1029983+(PERSIAN_EPOCH-1);
yday:=(jdn-jdn2)+1;
If yday <= 186 Then
iMonth:= -Sign(yday / 31) * round(-Abs(yday / 31))
Else
iMonth:= -Sign(((yday - 6) / 30)) * round(-Abs((yday - 6) / 30));
If iYear >= 0 Then
epbase:=iYear-474
Else
epbase:=iYear-473;
epyear:=474+(epbase Mod 2820);
If iMonth <= 7 Then
mdays:=(iMonth-1)*31
Else
mdays:=(iMonth-1)*30+6;
jdn2:=1+mdays+Trunc(((epyear*682)-110)/ 2816)+(epyear-1)*365+ Trunc(epbase / 2820)*1029983+(PERSIAN_EPOCH-1);
iDay:=(jdn-jdn2)+1;
aa:=inttostr(iYear)+"/"+inttostr(iMonth)+"/"+inttostr(iDay);
Miladi2Shamsi:=aa;
end;
اولین گام پردازش تصویر کار با رنگ نقاط (pixel) هستش. اما باید بگم توی حالت عادی شما 3 درجه رنگی از 3 رنگ اصلی آبی و سبز و قرمز برای هر نقطه دارید که با کم و زیاد شدن شدت هر مولفه اصلی رنگ حاصل تغییر میکنه . اما تو پردازش تصویر این فرمت اصلا به درد نمی خوره ! دلیلش اینه که شما معمولا نیاز به تشخیص یه محدوده رنگی خاص دارید مثلا رنگ حول و حوش صورتی, حالا با 3 رنگ اصلی چطور می خواید این محدوده رو تعیین کنید ؟! میشه گفت محاله ممکنه یا بهتر بگم اصلا عقلانی نیست دنبالش برید.!!!
پس باید دنبال شیوه ای برای اون باشیم!
برای هر رنگ ما 3 مشخصه می تونیم نام ببریم :
1- نام رنگ (چیز بهتری گیر نیووردم بهش بگم -> Hue ) :
این یعنی اینکه رنگ چیه ! مثلا میگی آبی یا آبی یکم متمایل به سبز یا ....
2- شدت رنگ :
اگه دقت کرده باشید هر رنگ میتونه پر رنگ یا کم رنگ باشه اما ماهیت ذاتی اون یه چیزه و فقط کم رنگ تر یا پررنگ تر شده به این میگن -> Saturation
3- روشنایی یا تیرگی رنگ :
یه رنگ رو می تونید بهش نور بتابونید که روشناییش زیاد بشه یا نور رو کم کنید که روشناییش کم بشه که میتونه انقدر کم بشه که سیاه بشه !! به این میگن->Intensity
امیدوارم تونسته باشن خوب برسونم منظورم چیه !
پس یه حوضه جدید که الهام گرفته از چشم هستش رو باهاش آشنا شدیم که کار روی رنگها برای تصمیم گیری روی مشخصات اون رو راحت میکنه. به این حوضه رنگی اصطلاحا HSI میگن که مخفف اون 3کلمه بالاست. شکل زیر نمودار تغییرات رنگ رو با توجه به این 3 مولفه نشون میده:
H بین 0 تا 360 هستش یعنی از قرمز تا سبز 120 درجه و از سبز تا آبی 120درجه و از آبی تا قرمز 120 درجه در جهت خلاف جهت حرکت عقربه های ساعت.
S بین 0 تا 100 هستش که از کم رنگ (0) تا پر رنگ (100)
I از 0 تا 100 هستش یعنی از تاریک(0) تا روشن(100)
چند نمونه از رنگها در 2 حوضه مذکور :
رنگ |
RGB مقادیر |
HSI مقادیر |
---|---|---|
سیاه |
(255,255,255) |
(0,0,0) |
سفید |
(255,255,255) |
(0,0,100) |
قرمز |
(255,0,0) |
(0,100,100) |
سبز |
(0,255,0) |
(120,100,100) |
آبی |
(0,0,255) |
(240,100,100) |
! قهوه ای |
(64,128,128) |
(180,50,50) |
حالا نیاز به این داریم که RGB مربوط به هر نقطه را به HSI تبدیل کنیم که رابطش رو به صورت سی نوشتم که r,g,b همون 3 رنگ آبی و سبز و قرمز هر نقطه هستش:
int min,max;
/////////////////////
if(r>g)
{
max=r;
min=g;
}
else
{
max=g;
min=r;
}
if(b>max)
max=b;
if(b<min )
min=b;
////////////////////
if(max==0)
{
i=0;
s=0;
h=0;
}
else
{
i=max*100/255;
s=(max-min)*100/max;
h=180*acos((((r-g)+(r-b))/2)/sqrt(pow(r-g,2)+(r-b)*(g-b)))/3.1415;
if(b>g)
h=360-h;
}