الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

استفسار حول التكبير والتدوير لصورة

بدأه ibr_exn في 6 يوليو 2009 · 16 رد · 2,315 مشاهدة · في قسم برمجة الألعاب و الرسوميات العام
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكــم ورحمـة الله وبركاتــه ،،

درست مادة الجرافيكس زمااااان من غير تطبيق وحاليا احاول تطبيق ما درسته باستخدام السي

ارجو ان تتحملوني وتتحملوا اسئلتي التي قد تبدو سخيفه :lol:

محتاج مثال بسيط ( بدون استخدام مكتبة جاهزة ) عن التدوير و التكبير لصورة او لشكل ، بمعنى اخر تطبيق مباشر لخوارزمية التكبير والتدوير.

،

الحمد لله الذي هدانا لهذا وماكنا لنهتدي لولا ان هدانا الله

#3

اشكرك خلدون على ردك .

مثلا عندي صورة حابب اخذ جزء منها وادوره او اكبره واحفظ الناتج في صورة جديده

او عندي صورة لشكل ( مثلث مثلا ) اريد ان اقوم بتكبيره او تدويره

اعتقد انه توجد مكتبات جاهزة لعمل ذلك ولكني اريد تطبيق الخوارزميات الخاصة بذلك بلغة السي بدون استخدام مكتبات جاهزه .

يعني تطبيق للاتي :

http://en.wikipedia.org/wiki/Scaling_(geometry)

http://en.wikipedia.org/wiki/Rotation_matrix

ارجو ان يكون السؤال واضح

الحمد لله الذي هدانا لهذا وماكنا لنهتدي لولا ان هدانا الله

#4

اهلا وسهلا بك

واضح انو سؤالك كتير مبتدئ لكن تطبيق هذه المفاهيم يعتبر شيء مهم واساسي في الرسم الحاسوبي بشكل عام.

فمثلا في الالعاب ستضطر دائما الى التعامل مع مثل هذه المفاهيم.

التطبيق سهل جداً. كل ما عليك ان تعبي احداثيات نقاط مضلع معين في مصفوفة.

اكتب دالة الدوران ودالة التكبير، بحيث تستقبل مصفوفة النقاط وترجع المصفوفة بعد التحويل.

بالمختصر:

createArray of points كل عنصر يحتوي على x,y للنقطة

//first point:

points[0][0] = 10

points[0][1] = 15

//secondpoint:

points[1][0] = 12

points[1][1] = 20

.......

ارسم النقاط على الشاشة وبينها خطوط حتى تكون على شكل مضلع

ارسل المصفوفة الى دالة التكبير او الدوران

(الدالة تقوم بضرب كل نقطة بمصفوفة الدوران او التكبير)

يرجع من الدالة النقاط الجديدة بعد التحويل

ارسم الشكل الجديد على الشاشة

وهكذا تكون قد طبقت التكبير والتدوير :)

سهل ، اليس كذلك؟ :lol:

تم تعديل هذه المشاركة بواسطة Amjad.IT في 7 يوليو 2009 في 00:08

#5

هل يمكن التوضيح بمثال بلغة السي بحيث ادخل له مثلا صورة 500*500 واخذ الجزء 200*300 واعمل عليه التكبير او التدوير !

الحمد لله الذي هدانا لهذا وماكنا لنهتدي لولا ان هدانا الله

#6

السلام عليكــم ورحمـة الله وبركاتــه ،،

طبعا المثال هنا إستكمالا لما قالة الأخ أمجد

إليك هذا ال Pseudo Code طبعا لا يمكن إعتباره كود :happy:

لا تظن أن الكود كبير لأنه ليس كذلك :lol: ولكنه متكامل :D

المثال يقوم بقراءة صورة و يقوم بتكبيرها إلى الضعف، و تدويرها بزاوية 30 درجه حول نقطة الأصل.

[color= #993333;]struct pixle[color= #009900;]{   [color= #666666; font-style: italic;]///  struct contain the the position and color for a pixle

	[color= #993333;]int color;

	[color= #993333;]int x,y;

[color= #009900;]};

 

[color= #993333;]void imageToPixleList[color= #009900;]([color= #993333;]int [color= #339933;]*img,pixle [color= #339933;]*pix[color= #009900;])[color= #009900;]{   [color= #666666; font-style: italic;]/// Convert the image to pixles list that contain
 the position and color of each pixle

	[color= #993333;]int counter[color= #339933;]=[color= #cc66cc;]0;

	[color= #b1b100;]for[color= #009900;]([color= #993333;]int i[color= #339933;]=[color= #cc66cc;]0;i<[color= #cc66cc;]300;i[color= #339933;]++[color= #009900;])

		[color= #b1b100;]for[color= #009900;]([color= #993333;]int j[color= #339933;]=[color= #cc66cc;]0;j<[color= #cc66cc;]300;j[color= #339933;]++[color= #009900;])[color= #009900;]{

			pix[color= #009900;][counter[color= #009900;]].[color= #202020;]x[color= #339933;]=i;

			pix[color= #009900;][counter[color= #009900;]].[color= #202020;]y[color= #339933;]=j;

			pix[color= #009900;][counter[color= #009900;]].[color= #202020;]color[color= #339933;]=img[color= #009900;][i[color= #009900;]][color= #009900;][j[color= #009900;]];   [color= #666666; font-style: italic;]/// read the color from the image

			counter[color= #339933;]++;

		[color= #009900;]}

	[color= #b1b100;]return pix;

[color= #009900;]}

 

[color= #993333;]void createRotationMatrix[color= #009900;]([color= #993333;]int [color= #339933;]*mtx, [color= #993333;]int val[color= #009900;])[color= #009900;]{

 

	[color= #808080; font-style: italic;]/* The Rotation Matrix

 

[color= #808080; font-style: italic;]		[cos(val)   -sin(val)   0]

[color= #808080; font-style: italic;]		[sin(val)   cos(val)    0]

[color= #808080; font-style: italic;]		[  0             0      1]

 

[color= #808080; font-style: italic;]	*/

 

	[color= #666666; font-style: italic;]// Fill the scaling Matrix

	mtx[color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #339933;]=cos[color= #009900;](val[color= #009900;]);

	mtx[color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #339933;]=-sin[color= #009900;](val[color= #009900;]);

	mtx[color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

 

	mtx[color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #339933;]=sin[color= #009900;](val[color= #009900;]);

	mtx[color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #339933;]=cos[color= #009900;](val[color= #009900;]);

	mtx[color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

 

	mtx[color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

	mtx[color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

	mtx[color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

 

	[color= #b1b100;]return mtx;

[color= #009900;]}

 

[color= #993333;]void createScalingMatrix[color= #009900;]([color= #993333;]int [color= #339933;]*mtx, [color= #993333;]int sx, [color= #993333;]int sy[color= #009900;])[color= #009900;]{

	[color= #808080; font-style: italic;]/* The Scaling Matrix

 

[color= #808080; font-style: italic;]		[sx   0   0]

[color= #808080; font-style: italic;]		[0   sy   0]

[color= #808080; font-style: italic;]		[0    0   1]

 

[color= #808080; font-style: italic;]	*/

 

	[color= #666666; font-style: italic;]// Fill the scaling Matrix

	mtx[color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #339933;]=sx;

	mtx[color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

	mtx[color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

 

	mtx[color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

	mtx[color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #339933;]=sy;

	mtx[color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

 

	mtx[color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

	mtx[color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

	mtx[color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #339933;]=[color= #cc66cc;]0;

 

	[color= #b1b100;]return mtx;

[color= #009900;]}

 

[color= #993333;]void Transform[color= #009900;](pixle [color= #339933;]*lst, [color= #993333;]int [color= #339933;]*mtx[color= #009900;])[color= #009900;]{    

		[color= #993333;]int point[color= #009900;][[color= #cc66cc;]3[color= #009900;]];

 

		[color= #b1b100;]for[color= #009900;]([color= #993333;]int i[color= #339933;]=[color= #cc66cc;]0;i<[color= #cc66cc;]300[color= #339933;]*[color= #cc66cc;]300;i[color= #339933;]++[color= #009900;])[color= #009900;]{

			point[color= #009900;][[color= #cc66cc;]0[color= #009900;]][color= #339933;]=lst[color= #009900;][i[color= #009900;]].[color= #202020;]x;

			point[color= #009900;][[color= #cc66cc;]1[color= #009900;]][color= #339933;]=lst[color= #009900;][i[color= #009900;]].[color= #202020;]y;

			point[color= #009900;][[color= #cc66cc;]2[color= #009900;]][color= #339933;]=[color= #cc66cc;]1;

 

			point[color= #339933;]=MatrixMultiply[color= #009900;](mtx,point[color= #009900;]);   [color= #666666; font-style: italic;]/// this is just a function that multiplies a 3*1 matrix 
By 3*3 matrix

			[color= #666666; font-style: italic;]/// this function return a 3*1 Matrix

			lst[color= #009900;][i[color= #009900;]].[color= #202020;]x[color= #339933;]=point[color= #009900;][[color= #cc66cc;]0[color= #009900;]];    [color= #666666; font-style: italic;]/// get the new valuse

			lst[color= #009900;][i[color= #009900;]].[color= #202020;]y[color= #339933;]=point[color= #009900;][[color= #cc66cc;]1[color= #009900;]];

		[color= #009900;]}

[color= #009900;]}

 

[color= #993333;]void pixleListToImage[color= #009900;](pixle [color= #339933;]*pix,[color= #993333;]int [color= #339933;]*img[color= #009900;])[color= #009900;]{   [color= #666666; font-style: italic;]/// Convert the pixle list to normal image

 

	[color= #b1b100;]for[color= #009900;]([color= #993333;]int i[color= #339933;]=[color= #cc66cc;]0;i<[color= #cc66cc;]300[color= #339933;]*[color= #cc66cc;]300;i[color= #339933;]++[color= #009900;])[color= #009900;]{

		[color= #b1b100;]if[color= #009900;]( pix[color= #009900;][i[color= #009900;]].[color= #202020;]x>[color= #339933;]=[color= #cc66cc;]0 [color= #339933;]&& pix[color= #009900;][i[color= #009900;]].[color= #202020;]x pix[color= #009900;][i[color= #009900;]].[color= #202020;]x<[color= #cc66cc;]300 [color= #339933;]&& pix[color= #009900;][i[color= #009900;]].[color= #202020;]y>[color= #339933;]=[color= #cc66cc;]0 [color= #339933;]&& pix[color= #009900;][i[color= #009900;]].[color= #202020;]y<[color= #cc66cc;]300[color= #009900;])   [color= #666666; font-style: italic;]/// if the new pix
le is out the boundaries of the orginal image then ignor it

			img[color= #009900;][pix[color= #009900;][i[color= #009900;]].[color= #202020;]x[color= #009900;]][color= #009900;][pix[color= #009900;][i[color= #009900;]].[color= #202020;]y[color= #009900;]][color= #339933;]=pix[color= #009900;][i[color= #009900;]].[color= #202020;]color;

	[color= #009900;]}

[color= #009900;]}

 

[color= #993333;]void main[color= #009900;]([color= #009900;])[color= #009900;]{

	[color= #993333;]int img[color= #009900;][[color= #cc66cc;]300[color= #009900;]][color= #009900;][[color= #cc66cc;]300[color= #009900;]];

	pixle imgPixlesList[color= #009900;][[color= #cc66cc;]300[color= #339933;]*[color= #cc66cc;]300[color= #009900;]];

	[color= #993333;]int scalingMatrix[color= #009900;][[color= #cc66cc;]3[color= #009900;]][color= #009900;][[color= #cc66cc;]3[color= #009900;]];

	[color= #993333;]int rotationMatrix[color= #009900;][[color= #cc66cc;]3[color= #009900;]][color= #009900;][[color= #cc66cc;]3[color= #009900;]];

	[color= #993333;]int rotationAngle[color= #339933;]=[color= #cc66cc;]30;

	[color= #993333;]int XscalingFactor[color= #339933;]=[color= #cc66cc;]2;   [color= #666666; font-style: italic;]/// The amount of needed scaling >1 for larger  < 1 and >0 for smaller
   (each X axis and Y axis has scaling)

	[color= #993333;]int YscalingFactor[color= #339933;]=[color= #cc66cc;]2;

 

	img[color= #339933;]=readImage[color= #009900;]([color= #009900;]);

	imageToPixleList[color= #009900;](img,imgPixlesList[color= #009900;]);

 

	createScalingMatrix[color= #009900;](scalingMatrix, XscalingFactor, YscalingFactor[color= #009900;]);

	Transform[color= #009900;](imgPixlesList,scalingMatrix[color= #009900;]);

 

	createRotationMatrix[color= #009900;](rotationMatrix, rotationAngle[color= #009900;]);

	Transform[color= #009900;](imgPixlesList,rotationMatrix[color= #009900;]);

 

	pixleListToImage[color= #009900;](imgPixlesList, img[color= #009900;]);

[color= #009900;]}

هناك بعض الملاحظات على الكود، و سأضع بعضها هنا.

أولا في ال Main

نعرف صورة على شكل مصفوفة (في المثال الحقيقي قد يكون لديك تعريف آخر للصورة)

نعرف مصفوفة تحتوي على كل بكسلات الصورة (كل بكسل عبارة عن Struct يحتوي X و Y و اللون)

بعدها نعرف مصفوفات التحويل (حجمها 3*3 للعالم ثنائي الأبعاد)

نعرف زاوية الدوران (طبعا الدوران يتم حول نقطة الأصل)

نعرف معامل التحجيم (كم تريد أن تكبر أو تصغر الصورة)

بعد ذلك نقرأ الصورة (استخدم الطريقة التي تريدها في التطبيق الحقيقي)

بعدها نقوم بتحويل الصورة إلى قائمة بالبكسلات (لتسهيل التعامل معها ليس أكثر)

بعد ذلك نستدعي دالة إنشاء مصفوفة التحجيم حيث نرسل لها معاملات التحجيم في X و Y

بعد ذلك نستدعي دالة التحويل ، حيث تقوم هذه الدالة بضرب مصفوفتين ببعض (لم أكتب دالة ضرب المصفوفات لإني لا أذكر ضرب المصفوفات "فاقد الشيئ لا يعطي :lol: " )

بعدها نستدعي دالة إنشاء مصفوفة التدوير بنفس الطريقه، و بعدها نقوم بعملية التحويل

في النهاية نقوم بإرجاع الصورة من قائمة بكسلات إلى حالتها الطبيعية . (لاحظ في هذه الدالة اننا نهمل البكسلات التي اصبح موقعها الجديد خارج حدود الصورة الأصلية)

مفضل قبل إستدعاء هذه الدالة أن تملأ الصورة باللون الاسود (لأنه سينتج مناطق جديده لا تحتوي على شيئ)

و الحمد لله رب العالمين -_-

أرجو أن اكون قد وضحت الموضوع وجاهز لأي سؤال آخر

طبعا للحصول على مزيد من المعلومات عن مصفوفات التحويل راجع الدرس

المصفوفات و برمجة الألعاب

تقبل تحياتي

#7

شكرا خلدون

كفيت و اوفيت

جاري التجربه

الحمد لله الذي هدانا لهذا وماكنا لنهتدي لولا ان هدانا الله

#8

بالمناسبة لأدي ملاحظة صغيرة ..

القيام بتكبير وتدوير صورة يختلف عن تدوير وتكبير مضلّع .

في الغالب , بعض البرامج تتعامل مع تدوير الصورة بشكل شبيه بالتالي :

قبل :

post-42837-1246997654_thumb.jpg

بعد:

post-42837-1246997679_thumb.jpg

يعني عمليّة التدوير للصورة , تحتاج لخطوات معيّنة ( لايسألني أحد عنها ;) ) .

أما مسألة تكبير الصورة , فهي أيضا تخضع لخوارزميات أخرى :

http://en.wikipedia.org/wiki/Image_scaling

http://www.alglib.net/interpolation/spline2d.php

الخلاصة , أن موضوع تكبير و تدوير الصور أعقد من تكبير وتدوير الأشكال ( المضلّعات ) .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#9

ولكن العمليات التي تتم على المضلعات من المكن تطبيقها بسهولة على الصور العاديه كما لاحظنا,

يعني البرنامج الذي كتبته بإمكانه إنتاج المثال الذي وضعته ولكن مع بعض الإضافه (حيث يجب تكبير مساحة الصورة بحيث تتسع لكامل الصورة الجديدة)

اقتباس
يعني عمليّة التدوير للصورة , تحتاج لخطوات معيّنة ( لايسألني أحد عنها ) .

ما هي ؟؟ :):)

بالنسبة للتكبير فعلا هناك طرق أخرى ممكن إستخدامها

اقتباس
الخلاصة , أن موضوع تكبير و تدوير الصور أعقد

لا أعتقد :)

#10

طيّب ...

أنت تفكّر في الصورة على أنها مصفوفة من النقاط كل نقطة لها ثلاث صفات ( X, Y, COLOR ) .

1- تقوم بانشاء صورة جديدة كبيرة بما فيه الكفاية .. وتضع القيم الابتدائية بالأسود .

2- تقوم باستخراج النقاط من الصورة الاصلية .

3- تضرب تلك النقاط بالمصفوفة .

4- تقوم بنسخ النقاط الجديدة في الصورة الجديدة ( 1 ) .

لاننسى أيضا .. أن ناتج بعض العمليات هو كسور ( مكلف ) .. بينما من المفروض أن البكسل لايوجد فيه كسر , وأغلب برامج الرسم ( الفوتوشوب ) تتعامل مع أعداد عشرية ( بكسل ) , وليس كما في البرامج ثلاثية البعد مثل الثري دي ماكس .

أعتقد يوجد شيء أفضل من كذا ... مرّة أخرى ( لايسألني أحد :) ) ...

تم تعديل هذه المشاركة بواسطة الشمري في 7 يوليو 2009 في 23:55

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#11

اهلا اخي الشمري

الشمري كتب:
أنت تفكّر في الصورة على أنها مصفوفة من النقاط كل نقطة لها ثلاث صفات ( X, Y, COLOR ) .

هي فعلاً كذلك :P

الشمري كتب:
لاننسى أيضا .. أن ناتج بعض العمليات هو كسور ( مكلف ) .. بينما من المفروض أن البكسل لايوجد فيه كسر

تجاهل الكسر

الشمري كتب:
أعتقد يوجد شيء أفضل من كذا ... مرّة أخرى ( لايسألني أحد :) ) ...

لماذا هذا التكتم :nose_patch: ، هل هو سر ؟؟ :angry:

وجدت بعض الخوارزميات للتكبير ، لكن لم اجد شيء محدد للتدوير.

#12

لا ليس سر ... لكن لا أعرف .. هل يجب أن أقول هذا أمام الملأ :D .

عموماً .. هذا رابط لمكتبة المستقبل :-) :

http://www.boost.org/doc/libs/1_39_0/libs/...mple/affine.cpp

الممكتبة برعاية Adobe , يبدو أنها خرجت من معاملها ... يمكن النظر الى source code

#include <boost/gil/image.hpp>
#include <boost/gil/typedefs.hpp>
#include <boost/gil/extension/io/jpeg_io.hpp>
#include <boost/gil/extension/numeric/sampler.hpp>
#include <boost/gil/extension/numeric/resample.hpp>

int main() {
	using namespace boost::gil;

	rgb8_image_t img;
	jpeg_read_image("test.jpg",img);

	// test resample_pixels
	// Transform the image by an arbitrary affine transformation using nearest-neighbor resampling
	rgb8_image_t transf(rgb8_image_t::point_t(view(img).dimensions()*2));
	fill_pixels(view(transf),rgb8_pixel_t(255,0,0));	// the background is red

	matrix3x2<double> mat = matrix3x2<double>::get_translate(-point2<double>(200,250)) *
							matrix3x2<double>::get_rotate(-15*3.14/180.0);
	resample_pixels(const_view(img), view(transf), mat, nearest_neighbor_sampler());
	jpeg_write_view("out-affine.jpg", view(transf));

	return 0;
}

تم تعديل هذه المشاركة بواسطة الشمري في 8 يوليو 2009 في 00:48

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#13

يبدو ان الموضوع ليس بالبساطة التي تصورتها. :wacko:

اقتباس
وجدت بعض الخوارزميات للتكبير ، لكن لم اجد شيء محدد للتدوير.

اعتقد انه يمكن الاستفادة من الحالة الخاصة من التدوير عن طريق استخدام مقلوب المصفوفة ( جعل الصفوف اعمدة والاعمدة صفوف) .

تم تعديل هذه المشاركة بواسطة ibr_exn في 8 يوليو 2009 في 21:22

الحمد لله الذي هدانا لهذا وماكنا لنهتدي لولا ان هدانا الله

#14

لكن مالذي ستسفيده ؟! , لم أفهم فكرتك ... قلب المصفوفة .. سفيدنا فقط في تغيير طريقة الضرب ( من اليسار الى اليمين أو من اليمين الى اليسار ) .. للتحويل من نظام Row Major Order الى Column Major Order .

أظن كما قال الاخوة ( اقتنعت الان :) ) .. تدوير صورة لايختلف كثيراً عن تدوير مضلّع , باستثناء اضافة بعض الخطوات الروتينية البسيطة .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#16
اقتباس
لكن مالذي ستسفيده ؟! , لم أفهم فكرتك ... قلب المصفوفة .. سفيدنا فقط في تغيير طريقة الضرب ( من اليسار الى اليمين أو من اليمين الى اليسار ) .. للتحويل من نظام Row Major Order الى Column Major Order .

لقد فهمت من ابراهيم انه يمكن الاستفادة من الحالات الخاصة كتدوير الشكل 90،180،270 درجة.

فمثلا اذا اردنا تدوير الشكل 90 درجة، فيمكن ذلك بسهولة بجعل الصفوف اعمدة والاعمدة صفوف (بدون استخدام مصفوفة دوران او ضرب مصفوفات)

فالمصفوفة التي نريد قلبها هي الصورة نفسها (لأنها عبارة مصفوفة).

لاحظ الصورة التالية:

post-68609-1247092102_thumb.gif

لقد تم تدوير الشكل 90 درجة، لاحظ ان العمود الاول في الصورة 1 هو نفسه الصف الاول في الصورة 2

إذن لتدوير الشكل 90 درجة، يكفي ان نأخذ الاعمدة واحداً تلو الآخر ونرتبها على شكل صفوف، مع ملاحظة ان أبعاد الصورة المقلوبة ستكون عكس الصورة الاصلية، فإذا كانت 200×300، فإنه عند قلبها ستكون 300×200.

بلغة المبرمجين :)

img2 = new image
img2.width = img1.height
img2.height = img1.width

for (i=0;i<img2.width;i++)
	 for(j=0;j<img2.height;j++)
		  img2[j] = img1[j];

هكذا ببساطة نلف الشكل 90 درجة،

الدوران 180: نعكس ترتيب الاعمدة ونعكس ترتيب الصفوف، بمعنى ان العمود الاول يصبح العمود الاخير، والصف الاول يصبح الصف الأخير.

الدوران 270: دوران 90 درجة ثم 180 درجة.

:wink:

تم تعديل هذه المشاركة بواسطة Amjad.IT في 9 يوليو 2009 في 01:43

#17

شكراً .. الان واضحة ,

كنت أعتقد أن الاخ Ibr_exn , أنه يريد قلب مصفوفة الدوران نفسها ..

اذاً الكلام هو في قلب مصفوفة الصورة نفسها , فكرة جيدة :D

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

مواضيع مشابهة