inverse לתמונה

  • פותח הנושא smat
  • פורסם בתאריך

smat

New member
inverse לתמונה

אני מנסה לבצע inverse לתמונה. יצרתי ביטמפ מקובץ והשתמשתי ב setpixel בשביל לעשות inverse ניסתי לשנות את הערך של כל פיקסל בנפרד בצורה הבאה:
for (int i = 0; i < pictureBox.Width ; i++) { for (int j = 0; j < pictureBox.Height; j++) { bitmapTemp.SetPixel(i, j, Color.FromArgb(255 - bitmapTemp.GetPixel(i, j).R, 255 - bitmapTemp.GetPixel(i, j).G, 255 - bitmapTemp.GetPixel(i, j).B)); } }​
וכמובן שזה לקח יותר מדי זמן אני חושב שאולי יש דרך לעבוד על תמונה בלי לגשת לכל פיקסל בנפרד.ובטוח שיש דרך מהירה יותר לעשות inverse יותר מהר מזה. יכול להיות שזה קשור למרחב השמות using System.Drawing.Imaging ?
 

smat

New member
מצאתי משהו אבל...

מצאתי פרוייקט ברשת לעיבוד תמונה ברשת(אני צירפתי לינק למטה) אבל ממש לא הבנתי מה הוא עושה שם הינה הפונקציה ל Invert
public static bool Invert(Bitmap b) { // GDI+ still lies to us - the return format is BGR, NOT RGB. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int stride = bmData.Stride; System.IntPtr Scan0 = bmData.Scan0; unsafe { byte* p = (byte*)(void*)Scan0; int nOffset = stride - b.Width * 3; int nWidth = b.Width * 3; for (int y = 0; y < b.Height; ++y) { for (int x = 0; x < nWidth; ++x) { p[0] = (byte)(255 - p[0]); ++p; } p += nOffset; } } }​
משהו מבין?
 

nadav1974

New member
לי זה נראה בדיוק אותו דבר

ברמת העיקרון, רק בלי לעבוד אם קריאות ל-SetPixel, אלא על הזיכרון של הביטמפ, כמו שאפשר לעשות ב-C/C++.
 

smat

New member
עוד לא ממש התעסקתי

עם מצביעים או עם BitmapData כנראה שאני צריך לשבת על זה קצת
 

smat

New member
מצאתי עוד דרך

אפשר לעבוד בלי מצביעים קיימת מתודה בשם: (...)System.Runtime.InteropServices.Marshal.Copy "Copies data from a managed array to an unmanaged memory pointer, or from an unmanaged memory pointer to a managed array." בקיצור מעבירה את המידע מהזכרון למערך בייטים וההיפך. וזו הפונקציה ל invert:
void Invert(Bitmap b) { BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); IntPtr scan0 = bmData.Scan0; int bytes = b.Width * b.Height * 3; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(scan0, rgbValues, 0, bytes); for (int i = 0; i < rgbValues.Length; i++) { rgbValues = (byte)(255 - rgbValues); } System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, scan0, bytes); b.UnlockBits(bmData); }

השאלה הוי עם יש יתרון לעבוד עם מצביעים?
 

nadav1974

New member
זה כמובן יעבוד פחות מהר

היות ויש כאן שתי העתקות נוספות.
 

smat

New member
כניראה שכן אבל אני לא הרגשתי בהבדל

גם כשבדקתי עם תמונות ברזולוציה גדולה (1700x2200)
 

nadav1974

New member
תלוי מה הדרישה שלך

אם זה בשביל תכנה קטנה, או בתור חלק לתכנה גדולה, זה מן הסתם בסדר. אם אתה עושה שרת, שעושה את זה הרבה פעמים כל שנייה, זה לא כ"כ בסדר.
 
למעלה