Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [VC#] Быстрое копирование Bitmap, Самый оптимальный способ. 
:(
    Опции темы
MuForum
Дата 1.5.2009, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Доброе время суток!
Работаю на "Microsoft Visual Studio 2008". Язык программирования C#.

# Задача: Реализовать быстрое копирование изображения.
- Сначала может показаться, что тут ничего сложного нету, однако, если графические файлы достаточно большого размера, то стандартный способ является достаточно долгим.

# 1 способ: (В лоб)
Код

Bitmap newImg = new Bitmap(oldImg);


# 2 способ: (Копирование всего участка памяти)
Код

Bitmap newImg = (Bitmap)oldImg.Clone(); // ICloneable - Clone()

P.S. -> Данный способ очень быстрый, однако возникают проблемы при использовании функции RotateFlip() частенько вылетает ошибка. (Чаще всего с форматом *.bmp)
-- Текст ошибки: "ExternalExtension was unhandled. A generic error occurred in GDI+."


# 3 способ: (Примерно в два раза быстрее чем вариант в лоб)
Код

private Bitmap CopyBitmap(Bitmap source)
{
   Bitmap bmp = new Bitmap(source.Width, source.Height, source.PixelFormat);
   Graphics g = Graphics.FromImage(bmp);
   g.DrawImage(source, 0, 0, source.Width, source.Height);
   g.Dispose();
   // ----
   return bmp;
}

P.S. -> Пример позаимствован с MSDN.


# 4 способ:
Код

private Bitmap CloneBitmap(Bitmap srcBmp)
{
   Bitmap dstBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
   BitmapData srcBmpData = srcBmp.LockBits(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
   BitmapData dstBmpData = dstBmp.LockBits(new Rectangle(0, 0, dstBmp.Width, dstBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
   unsafe
   {
      int* srcVal = (int*)srcBmpData.Scan0;
      int* dstVal = (int*)dstBmpData.Scan0;
      int iSize = srcBmpData.Width * srcBmpData.Height;
      for (int i = 0; i < iSize; i++, srcVal++, dstVal++) *dstVal = *srcVal;
   }
   srcBmp.UnlockBits(srcBmpData);
   dstBmp.UnlockBits(dstBmpData);
   return dstBmp;
}

P.S. -> Оптимизированный пример от "-Mikle-".



# Результаты тестирования:
Цитата

1. Изображение 189x103.
-- 1 способ: 0-1 мсек.
-- 2 способ: 0 мсек.
-- 3 способ: 1 мсек.
-- 4 способ: 0 мсек.
2. Изображение 805x563.
-- 1 способ: 9 мсек.
-- 2 способ: 0 мсек.
-- 3 способ: 5 мсек.
-- 4 способ: 8 мсек.
3. Изображение 4941x6936.
-- 1 способ: ~730 мсек.
-- 2 способ: 0 мсек.
-- 3 способ: ~350 мсек.
-- 4 способ: ~565 мсек.



P.S. -> Парни, может кто-то подскажет ещё какие-то способы?

Это сообщение отредактировал(а) MuForum - 10.5.2009, 11:07


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
-Mikle-
Дата 1.5.2009, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 17
Всего: 59



Думаю что быстрее, чем этот способ, не получится. Попробуй.
Код

        private Bitmap CloneBitmap(Bitmap srcBmp)
        {
            Bitmap dstBmp = new Bitmap(srcBmp.Width, srcBmp.Height);

            BitmapData srcBmpData = srcBmp.LockBits(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            BitmapData dstBmpData = dstBmp.LockBits(new Rectangle(0, 0, dstBmp.Width, dstBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            unsafe
            {
                int* srcVal = (int*)srcBmpData.Scan0;
                int* dstVal = (int*)dstBmpData.Scan0;
                for (int i = 0; i < (srcBmpData.Width * srcBmpData.Height); i++, srcVal++, dstVal++)
                    *dstVal = *srcVal;
            }
            srcBmp.UnlockBits(srcBmpData);
            dstBmp.UnlockBits(dstBmpData);

            return dstBmp;
        }



--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0442 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.