PDA

View Full Version : سوال: مشکل پیدا کردن عکسی که روی آن کلیک شده



یوسف زالی
جمعه 22 مهر 1390, 06:25 صبح
با سلام خدمت همه دوستان.
من چند تا عکس دارم که شکلهای پازل jigsaw رو در اون درست کردم.
مشکل من اینجاست که چون عکس ها رو باید transparent می کردم وقتی محدوده مخفی عکسی روی محدوده مرئی عکس مورد نظر من هست نمی تونم به عکس درست دسترسی داشته باشم و عکسی که انتخاب می شه عکس آبی هست. در صورتی که قرمز باید انتخاب بشه.
76577
هرچی فکر کردم راه حلی به ذهنم نرسید.
به نظر شما با چه راه حلی می شه این مساله رو حل کرد؟
ممنونم

MohsenB
جمعه 22 مهر 1390, 10:38 صبح
سلام

یه راه برا شما اینه که ایمیج رو بصورت روشی که فرم رو شکل (Shape ) میدن انجام بدین .
برای این کار لازم هست که کنترل مورد نظر مانند فرم یک دستگیره داشته باشد که کنترل ایمیج این دستگیره را ندارد .
یک راه حل این است که هر ایمیج رو درون یه Panel بزارین و برای راحتی کار خاصیت AutoSize پنل رو True کنید .

بعد این کدها رو تو برنامتون بنویسید :


type
TRGBArray = array[0..32767] of TRGBTriple;
pRGBArray = ^TRGBArray;



function CreateRegion(Bmp: TBitmap): HRGN;
var
X, Y, StartX:Integer;
Excl: THandle;
Row: PRGBArray;
TransparentColor: TRGBTriple;
begin
Bmp.PixelFormat := pf24Bit;
Result := CreateRectRGN(0, 0, Bmp.Width, Bmp.Height);
for Y := 0 to Bmp.Height - 1 do
begin
Row := Bmp.Scanline[Y];
if Y = 0 then begin
TransparentColor := Row[0];
end;
StartX := -1;
for X := 0 to Bmp.Width do begin
if(X <> Bmp.Width) and
(Row[X].rgbtRed = TransparentColor.rgbtRed) and
(Row[X].rgbtGreen = TransparentColor.rgbtGreen) and
(Row[X].rgbtBlue = TransparentColor.rgbtBlue) then
begin
if StartX = -1 then begin
StartX := X;
end;
end else begin
if StartX > -1 then begin
Excl := CreateRectRGN(StartX, Y, X, Y + 1);
try
CombineRGN(Result, Result, Excl, RGN_DIFF);
StartX := -1;
finally
DeleteObject(Excl);
end;
end;
end;
end;
end;
end;

توضیح اینکه این تابع رنگ نقطه (0,0) رو بعنوان رنگ ترنسپرنت انتخاب می کند .

برای نمونه میتونید این کد رو توی یه دکمه بنویسید و نتیجه رو ببینید :

procedure TForm1.btn1Click(Sender: TObject);
var i :HRGN;
begin
i:= CreateRegion(img1.Picture.Bitmap);
SetWindowRgn(pnl1.Handle, i, True);
end;


موفق باشید

یوسف زالی
جمعه 22 مهر 1390, 14:05 عصر
سلام دوست عزیز.
ممنونم که جواب دادی.
چند تا سوال دارم:
توابع CreateRectRGN و CombineRGN دقیقا چه عملی انجام می دن؟
و اینکه آیا با روش شما پنل مورد نظر کلا از حالت مستطیلی خارج می شه؟
یعنی اینکه اگر روی مناطقی کلیک بشه که در حالت مستطیلی وجود داره ، رویداد رو می گیره یا نه؟

MohsenB
جمعه 22 مهر 1390, 14:28 عصر
سلام دوست عزیز.
ممنونم که جواب دادی.
چند تا سوال دارم:
توابع CreateRectRGN و CombineRGN دقیقا چه عملی انجام می دن؟

ممنون

تابع CreateRectRGN یک منطقه چهار ضلعی رو درست میکنه - بیشتر (http://msdn.microsoft.com/en-us/library/dd183465%28v=vs.85%29.aspx)

تابع CombineRGN دو منطقه ( Region ) رو با هم ترکیب میکنه و توی منطقه اول میزاره - بیشتر (http://msdn.microsoft.com/en-us/library/dd183465%28v=vs.85%29.aspx)




و اینکه آیا با روش شما پنل مورد نظر کلا از حالت مستطیلی خارج می شه؟
یعنی اینکه اگر روی مناطقی کلیک بشه که در حالت مستطیلی وجود داره ، رویداد رو می گیره یا نه؟

بله.
خبر نمیگیره .

موفق باشید

یوسف زالی
جمعه 22 مهر 1390, 19:56 عصر
کارم راه افتاد.
ممنون دوست عزیز.