Оптимизация рисования области интереса (ROI) на изображении - PullRequest
0 голосов
/ 03 сентября 2011

Я рисую прямоугольную область ROI, затемняя область за ее пределами, как на этом изображении http://www.codeproject.com/script/Membership/Uploads/4613314/roi.jpg

Но image.MakeTransparent занимает слишком много времени.Как лучше всего увеличить скорость рисования?

void DrawRoi(Bitmap Image, RectangleF rect)
{
        Rectangle roi = new Rectangle();

        roi.X = (int)((float)Image.Width * rect.X);
        roi.Y = (int)((float)Image.Height * rect.Y);
        roi.Width = (int)((float)Image.Width * rect.Width);
        roi.Height = (int)((float)Image.Height * rect.Height);

        Stopwatch timer = new Stopwatch();
        timer.Start();
        // graphics manipulation takes about 240ms on 1080p image
        using (Bitmap roiMaskImage = CreateRoiMaskImage(ImageWithRoi.Width, ImageWithRoi.Height, roi))
        {
                using (Graphics g = Graphics.FromImage(ImageWithRoi))
                {                                
                        g.DrawImage(Image, 0, 0);
                        g.DrawImage(roiMaskImage, 0, 0);
                        Pen borderPen = CreateRoiBorderPen(ImageWithRoi);
                        g.DrawRectangle(borderPen, roi);
                }
        }
        Debug.WriteLine("roi graphics: {0}ms", timer.ElapsedMilliseconds);
        this.imagePictureBox.Image = ImageWithRoi;
}

Bitmap CreateRoiMaskImage(int width, int height, Rectangle roi)
{
        Bitmap image = new Bitmap(width, height, PixelFormat.Format32bppArgb);
        using (Graphics g = Graphics.FromImage(image))
        {
                SolidBrush dimBrush = new SolidBrush(Color.FromArgb(64, 0, 0, 0));
                g.FillRectangle(dimBrush, 0, 0, width, height);
                SolidBrush roiBrush = new SolidBrush(Color.Red);
                g.FillRectangle(roiBrush, roi);
                image.MakeTransparent(Color.Red);
                return image;
        }                
}

Pen CreateRoiBorderPen(Bitmap image)
{
        float width = ((float)(image.Width + image.Height) * 2.5f) / (float)(640 + 480);
        if (width < 1.0f)
                width = 1.0f;
        Pen pen = new Pen(Color.FromArgb(255, 0, 255, 0), width);
        return pen;
}

Ответы [ 3 ]

2 голосов
/ 05 сентября 2011

Не манипулируйте изображением вообще.Просто нарисуйте «затемнение» поверх вашего изображения.Вы можете добиться того же эффекта, например,

1) Рисуя большую полупрозрачную область по всему изображению с областью клипа, установленной на ROI

// Assume for simplicity the image is size w*h, and the graphics is the same size. 
// The ROI is a rectangle named roiRect.
g.DrawImageUnscaled(image, 0, 0 , w, h);
g.SetClip(roiRect);
g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Black)), 0, 0, w, h);
g.ResetClip();    

2) Рисованиеimage, затем затемняющий прямоугольник, затем roi-часть изображения поверх этого.

3) Рисуем 4 отдельных прямоугольника сверху / справа / слева / снизу, чтобы исключить ваш ROI.

1 голос
/ 05 сентября 2011

Я не вижу смысла в вызове .MakeTransparent вообще. При создании вашей маски изображение

Bitmap image = new Bitmap(width, height, PixelFormat.Format32bppArgb);

это уже прозрачно. Вместо этого лучше нарисовать dimBrush в виде четырех отдельных прямоугольников (областей выше / ниже / слева / справа от области интереса) и избегать рисования в области, которая уже прозрачна!

0 голосов
/ 20 марта 2012

Посмотрите на класс WriteableBitmap. В методе WritePixels вы можете определить ROI с Int32Rect.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...