سؤال

هذا هو الحل لعمل سلبي من صورة في نماذج C # دون أي DLL وطريقة فعالة وسريعة؟

هل كانت مفيدة؟

المحلول

أفضل طريقة للقيام بذلك تصل إلى البكسل مباشرة مع بيانات نقطية.

فقط لإضافة بعض تفاصيل التوقيت:

يؤدي الأداء على صورة 8 ميجابكسل (على 2.4 جيجا هرتز Core 2 Duo):

  • setpixel (~ 22 ثانية) - 220 مرة أبطأ
  • مصفوفة اللون، طريقة matajon أدناه (~ 750 milliseconds) - 7 مرات أبطأ
  • قم مباشرة بتأسيس بيانات الصورة النقطية (~ 100 milliseconds) - أسرع

لذلك، إذا لم تتمكن من الحصول على رمز غير آمن، فإن مصفوفة اللون أفضل بكثير من setpixel.

    public static void Negate(Bitmap image)
    {
        const int RED_PIXEL = 2;
        const int GREEN_PIXEL = 1;
        const int BLUE_PIXEL = 0;


        BitmapData bmData = currentImage.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat);

        try
        {
            int stride = bmData.Stride;
            int bytesPerPixel = (currentImage.PixelFormat == PixelFormat.Format24bppRgb ? 3 : 4);

            unsafe
            {
                byte* pixel = (byte*)(void*)bmData.Scan0;
                int yMax = image.Height;
                int xMax = image.Width;

                for (int y = 0; y < yMax; y++)
                {
                    int yPos = y * stride;
                    for (int x = areaSize.X; x < xMax; x++)
                    {
                        int pos = yPos + (x * bytesPerPixel);

                        pixel[pos + RED_PIXEL] = (byte)(255 - pixel[pos + RED_PIXEL]);
                        pixel[pos + GREEN_PIXEL] = (byte)(255 - pixel[pos + GREEN_PIXEL]);
                        pixel[pos + BLUE_PIXEL] = (byte)(255 - pixel[pos + BLUE_PIXEL]);                                                    
                    }

                }
            }
        }
        finally
        {
            image.UnlockBits(bmData);
        }

    }

إذا كنت مهتما، فإليك رمز مصفوفة اللون:

    public static void Negate(Bitmap image)
    {

            Bitmap clone = (Bitmap) image.Clone();

            using (Graphics g = Graphics.FromImage(image))
            {

                // negation ColorMatrix
                ColorMatrix colorMatrix = new ColorMatrix(
                    new float[][]
                        {
                            new float[] {-1, 0, 0, 0, 0},
                            new float[] {0, -1, 0, 0, 0},
                            new float[] {0, 0, -1, 0, 0},
                            new float[] {0, 0, 0, 1, 0},
                            new float[] {0, 0, 0, 0, 1}
                        });

                ImageAttributes attributes = new ImageAttributes();

                attributes.SetColorMatrix(colorMatrix);

                g.DrawImage(clone, new Rectangle(0, 0, clone.Width, clone.Height),
                            0, 0, clone.Width, clone.Height, GraphicsUnit.Pixel, attributes);
           }
    }

نصائح أخرى

انتقل من خلال جميع البكسل واحدا تلو الآخر (Bitmap.getPixel () أو أي شيء) وطرح قيم RGB من 0xFF لإنشاء بكسل من اللون السلبي. احفظ هذه البكسل صورة جديدة أو على نفس الصورة باستخدام (bitmap.setpixel ()) في نفس الموضع.

    // Retrieve the image.
    var image1 = new Bitmap(@"C:\Documents and Settings\All Users\" 
        + @"Documents\My Music\music.bmp", true);

    int x, y;

    // Loop through the images pixels to reset color.
    for(x=0; x<image1.Width; x++)
    {
        for(y=0; y<image1.Height; y++)
        {
            Color pixelColor = image1.GetPixel(x, y);
            Color newColor = Color.FromArgb(0xff - pixelColor.R
            , 0xff - pixelColor.G, 0xff - pixelColor.B);
            image1.SetPixel(x, y, newColor);
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top