PDA

View Full Version : سوال: شبیه سازی Select با استفاده از یک Image بر روی Image دیگری که تصویر رو نشون میده!



mbshareat
جمعه 29 دی 1391, 19:39 عصر
سلام
من میخوام از ساده ترین راه یه ناحیه از تصویر رو در برنامه خودم انتخاب کنم.
برای این منظور یه ScrollBox روی فرم گذاشتم و داخلش یه Imgae برای نمایش تصویر فایل بیت مپ قرار دادم(اسمش رو گذاشتم Img!).
برای شبیه سازی کادر انتخاب از یه Image دیگه که Transparent شده روی Image مربوط به تصویر استفاده می کنم(اسمش رو گذاشتم SelectImg). با بررسی فشار و حرکت و رها کردن ماوس روی تصویر(Img) مختصات کادر انتخاب(SelectImg) رو تنظیم می کنم.این هم کدش:

var
Form1: TForm1;
ImgMouseISDown:Boolean;

implementation

{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ScrollBox1.DoubleBuffered:=True;
SelectImg.Transparent:=True;
end;
procedure TForm1.ImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ImgMouseISDown:=True;
SelectImg.Left:=X;
SelectImg.Top:=Y;
SelectImg.Width:=0;
SelectImg.Height:=0;
SelectImg.Visible:=True;
end;
procedure TForm1.ImgMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
If ImgMouseISDown=False then
Exit;
SelectImg.Canvas.FillRect(SelectImg.ClientRect);
SelectImg.Width:=X-SelectImg.Left;
SelectImg.Height:=Y-SelectImg.Top;
DrawFocusRect(SelectImg.Canvas.Handle
,SelectImg.ClientRect);
end;
procedure TForm1.ImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ImgMouseISDown:=False;
SelectImg.Visible:=False;
end;
procedure TForm1.SelectImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ImgMouseISDown:=False;
SelectImg.Visible:=False;
end;


مشکل اینه که تا این قسمت کد رو حذف نکنم کدم کاری نمی کنه:
If ImgMouseISDown=False then
Exit;
در حالیکه این قسمت کد ضروریه!
مشکل دیگه اینه که ناحیه انتخاب از اندازه زمان طراحی بزگتر نمیشه و وقتی سعی می کنم بزرگترش کنم (البته با حذف دو سطر بالا) ناحیه انتخاب سفید میشه.
لطفا راهنماییم کنین.
این هم کل پروژه:
98613

MohsenB
جمعه 29 دی 1391, 20:32 عصر
با سلام

این جوری که شما لازم دارید نیاز به این کارها نداره . مثلا :

یه کنترل Shape بجای اون ایمیج سلکت قرار بدید و استایل ناحیه براشش رو به Clear و Pen رو به Dot تغییر بدید و کد زیر رو بنویسید :

procedure TForm1.ImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
shpSelectImg.SetBounds(X, Y, 0, 0);
end;

procedure TForm1.ImgMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
with shpSelectImg do begin
if Shift = [ssLeft] then begin
Width:= X - Left;
Height:= Y - Top;
end;
Visible:= Shift <> [ssRight];
end;
end;

توضیح اینکه با چپ کلیک میتونید انتخاب کنید و با راست کلیک ناحیه انتخاب رو انصراف بدید . امیدوارم بدست آوردن تصویر ناحیه انتخابی رو ( عکس محصور بین مختصات شیپ ) خودتون دیگه بتونید بنویسید .

موفق باشید

mbshareat
شنبه 30 دی 1391, 10:08 صبح
سلام
من خیلی بهش ور رفتم که بتونم از Image استفاده کنم که وقت زوم کردن هم کادر انتخاب متناسب باشه.
ولی یه مشکل دارم اون هم معکوس کردن رنگ تصویر برای نمایش کادر انتخابه.
9864598646
اگر میشد در این برنامه این یه خط کار کنه خوب بود:
SelectImg.Picture.Bitmap.Canvas.Pen.Mode:=pmNot;
ظاهرا چون focusRect از عمل Xor استفاده می کنه تاثیی نداره.
کسی میتونه کمک کنه؟

بهروز عباسی
شنبه 30 دی 1391, 11:26 صبح
معکوس کردن رنگ تصویر برای نمایش کادر انتخابه.
میخواید اون قسمتی که انتخاب شده رنگش معکوس بشه؟

بهروز عباسی
شنبه 30 دی 1391, 11:50 صبح
من میخوام از ساده ترین راه یه ناحیه از تصویر رو در برنامه خودم انتخاب کنم.
از این ساده تر

اینم عکس برنامه هنگام اجرا
98648
{...}
var
dx, dy: Integer;
mx, my: Integer;
mdown: boolean;
CLR_CLEAR: TColor;

procedure TForm3.img_SourceMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
dx := X;
dy := Y; // store mouse down x and y
{ mdown := true; }
with img_Source do
begin
Canvas.Brush.Style := bsClear;
Canvas.Pen.Style := psDash;
Canvas.Pen.Mode := pmNot;
mx := X;
my := Y;
Canvas.Rectangle(dx, dy, mx, my);
end;
end;

procedure TForm3.img_SourceMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
if ssLeft in Shift { mdown } then
begin
with img_Source do
begin
Canvas.Rectangle(dx, dy, mx, my);
mx := X;
my := Y;
Canvas.Rectangle(dx, dy, mx, my);
end;
end;
end;

procedure TForm3.img_SourceMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
r: Trect;

function normalizerect(r: Trect): Trect;
begin
result := r;
with result do
begin
if right < left then
begin
left := r.right;
right := r.left;
end;
if bottom < top then
begin
top := r.bottom;
bottom := r.top;
end;
end;
end;

begin
{ mdown := FALSE; }
img_Source.Canvas.Rectangle(dx, dy, mx, my);
img_Destination.Canvas.Brush.Color := CLR_CLEAR;
img_Destination.Canvas.FillRect(Rect(0, 0, img_Destination.Width,
img_Destination.Height));
r := normalizerect(Rect(X, Y, dx, dy));
img_Destination.Canvas.CopyRect(Rect(0, 0, r.right - r.left,
r.bottom - r.top), img_Source.Canvas, r);
end;

موفق باشید.

hp1361
شنبه 30 دی 1391, 17:58 عصر
سلام

دوستان میشه راهنمایی بفرمایند چطور نحوه کار ابزار Crop در فوتوشاپ رو شبیه سازی کنیم؟

یعنی اینکه کادری که کاربر رسم میکنه باقی بمونه و کاربر بتونه با دقت بیشتری تغییرش بده و بعد از زدن دکمه اینتر تغییرات اعمال بشه

ممنون

mbshareat
شنبه 30 دی 1391, 18:21 عصر
جناب آقای عباسی فکر نکنم نیازی به img_Destination باشه من که این قسمت رو حذف کردم مشکلی پیش نیومد!:

img_Destination.Canvas.Brush.Color := CLR_CLEAR;
img_Destination.Canvas.FillRect(Rect(0, 0, img_Destination.Width,
img_Destination.Height));
r := normalizerect(Rect(X, Y, dx, dy));
img_Destination.Canvas.CopyRect(Rect(0, 0, r.right - r.left,
r.bottom - r.top), Img.Canvas, r);


ولی دوست دارم بدونم با روش خودم هم میشه کاری کرد؟ اولش فکر می کردم بهتره تصویر رو مستقیما دستکاری نکنم ولی شاید فرقی نداشته باشه.
فایده استفاده از یه شیء روی Image تصویر تشخیص راحت تر فشار ماوس داخل ناحیه انتخاب برای جابجایی و غیره هستش(و همچنین Crop!)

بهروز عباسی
شنبه 30 دی 1391, 20:50 عصر
ولی دوست دارم بدونم با روش خودم هم میشه کاری کرد؟ اولش فکر می کردم بهتره تصویر رو مستقیما دستکاری نکنم ولی شاید فرقی نداشته باشه.
فایده استفاده از یه شیء روی Image تصویر تشخیص راحت تر فشار ماوس داخل ناحیه انتخاب برای جابجایی و غیره هستش(و همچنین Crop!)
من هنوز دقیقاً متوجه نشدم شما می خوای چکار کنی
کمی بیشتر توضیح بده شاید بتونم کاری کنم.

hp1361
شنبه 30 دی 1391, 22:10 عصر
سلام

راه حلی برای سوال من وجود نداره؟

بهروز عباسی
شنبه 30 دی 1391, 22:50 عصر
سلام

راه حلی برای سوال من وجود نداره؟
وجود که داره !

شما باید یک کنترل شفاف (فکر کنم Panel بشه) رو دقیقاً توی همون ناحیه انتخابت بسازی و اون کنترل رو هم طوری تنظیم کنی که قالبیت تغییر سایز به وسیله ماوس در زمان اجرا رو داشته باشه.
اگه بتونی کار بالا رو انجام بدی ناحیه انتخاب روی عکس میمونه و بعد تعیین اندازه دقیق با تابع CopyRect اون قسمت رو برش میزنی .

mbshareat
شنبه 30 دی 1391, 22:56 عصر
من یه برنامه ساده گرافیکی دارم.دارم از ابتدا یه برنامه دیگه میسازم که امکاناتش درست تر تنظیم شده باشه و امکانات برنامه قبلی رو در اون ادغام می کنم.
تو برنامه قبلی تنظیم رنگ و اندازه و وضوح و غیره داشتم. حتی از MagicWand هم استفاده کرده بودم.
میخوام تو برنامم بشه کپی و الصاق هم کرد و غیره نمیخوام خیلی از ترسیم و بیت مپ پس زمینه و غیره استفاده کنم چون باعث میشه حوصلم سر بره و به مشکل بر بخورم و کارم رو نیمه کاره ول کنم. میخوام ساده ترین راه رو برای انتخاب ناحیه و برش و انتقال و حذف و غیره داشته باشم. بهترین راهی که فعلا به نظرم میرسه ترسیم در Image هنگام تعیین ناحیه انتخاب و بعد حذف کادر انتخاب (ترسیم شده با DrawFocusRect) و نمایش یک Shape در محل هست.(احتمالا Paint هم از همین روش استفاده می کنه!)
یه نکته ریز هم بگم: اون از بین بردن ناحیه هنگام رها کردن ماوس دلیل نداشت و همینطوری گذاشته بودم!!!

راه حلی برای سوال من وجود نداره؟
از همون راه ساده ای که در پست 2 (http://barnamenevis.org/showthread.php?379757-%D8%B4%D8%A8%DB%8C%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-Select-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%DB%8C%DA%A9-Image-%D8%A8%D8%B1-%D8%B1%D9%88%DB%8C-Image-%D8%AF%DB%8C%DA%AF%D8%B1%DB%8C-%DA%A9%D9%87-%D8%AA%D8%B5%D9%88%DB%8C%D8%B1-%D8%B1%D9%88-%D9%86%D8%B4%D9%88%D9%86-%D9%85%DB%8C%D8%AF%D9%87!&p=1679764&viewfull=1#post1679764) اومده برای تعیین ناحیه انتخاب کنید بعد هنگام فشار ماوس روی Shape اون ناحیه رو در یه بیت مپ موقتی در پس زمینه که طول و عرض برابر با طول و عرض ناحیه Crop داشته باشه، کپی کنید (با CopyRect).
بعد Shape رو نامرئی کنید و بیت مپ رو FreeImage کنید و بعد با Assign بیت مپ حاوی تصویر ناحیه رو به Image.Picture.Bitmap انتساب بدید و بیت مپ پس زمینه رو حذف کنید(با Free).
در کل سوالتون برام واضح نبود که همین رو می خواستید بدونید یا عملیات مشخصی مد نظرتونه.(دانش من که ته کشید)

hp1361
یک شنبه 01 بهمن 1391, 12:16 عصر
سلام

من میخوام یه چیزی بشه مثل ابزار Crop توی فتوشاپ که میشه کاربر تغییرش بده،بچرخونتش و....

ممنون