Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Оптимизация создания Bitmap'a


Автор: Netman 28.7.2008, 13:50
Я создаю Bitmap кодом приведенным ниже, проблема в том что когда разрешение Bitmap большое, например [1500;1500], все начинает заметно тормозить. Вопрос как еще с оптимизировать? (функция GetColorFromValue(Map[j, i]) не влияет на производительность)

 
Код

      
            Bitmap bmp = new Bitmap(Map.GetLength(0), Map.GetLength(1));           
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                System.Drawing.Imaging.ImageLockMode.ReadWrite,
                System.Drawing.Imaging.PixelFormat.Format24bppRgb);                        
            IntPtr ptr = bmpData.Scan0;
            bmpData.Stride = Map.GetLength(0) * 3;
            int bytes = bmpData.Stride * bmp.Height;
            byte[] source = new byte[bytes];           
            System.Runtime.InteropServices.Marshal.Copy(ptr, source, 0, bytes);            
            int k = 0;
            Color clr; 
            for (int i= 0; i <  Map.GetLength(1); i++)
                for (int j = 0; j < Map.GetLength(0); j++)
                {
                    clr = GetColorFromValue(Map[j, i]);                    
                    source[k++] = clr.R;
                    source[k++] = clr.G;
                    source[k++] = clr.B;
                }
            System.Runtime.InteropServices.Marshal.Copy(source, 0, ptr, bytes);
            bmp.UnlockBits(bmpData);           

Автор: Ctrl 28.7.2008, 20:21
Надеюсь я правильно понял задачу - генерация изображения по индексной карте цветов.
Предлагаю  такие шаги для оптимизации:
1. Выкинуть промежуточный массив и работать с данными битмапа напрямую (можно будет отказаться от операций копирования)
2. Использовать не 24 бита а 32 (это позволит избавиться от тяжелых преобразований компонент цвета,
  и избавит от невыровненных байтовых операций пересылки)
3. Убрать внутренний цикл

... в общем у меня на битмапе 1500х1500 выигрыш порядка 80%

Код

using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace ConsoleApplication3 {
    class Program {
        static void Main(string[] args) {
            int[,] map = new int[,] { { 0, 1, 0 }, { 1, 1, 1 }, { 1, 0, 1 }, { 0, 0, 1 } };
            Image img = ImageFromColorMap(map);
            img.Save(@"D:\img.bmp", ImageFormat.Bmp);
        }
        static Image ImageFromColorMap(int[,] Map) {
            int w = Map.GetLength(0);
            int h = Map.GetLength(1);
            Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            unsafe {
                Int32* data = (Int32*)bmpData.Scan0.ToPointer();
                Color color = Color.Empty;
                for(int i = 0; i < w * h; i++) {
                    color = GetColorFromValue(Map[i % w, i / w]);
                    data[i] = color.ToArgb();
                }
            }
            bmp.UnlockBits(bmpData);
            return bmp;
        }
        static Color[] colors = new Color[] { Color.Red, Color.Green };
        static Color GetColorFromValue(int index) {
            return colors[index & 0x01];
        }
    }
}


Автор: Netman 29.7.2008, 04:33
Да, прикольно конечно, спасибо!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)