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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как повысить быстродействие при работе с Gif 
:(
    Опции темы
libman
Дата 26.6.2007, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 31.10.2006

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



Задача стоит так, необходимо подсчитать количество цветов которые встречаются в картинке. Использую следующий код. Т.к. я не самый великий программист в этом мире то и скорость работы не велика, что можете подсказать для увеличения быстродействия. Мой код ниже.
Есть мысль попробовать с несколькими потоками или я не прав?


 Color[] masOfColor = new Color[256];
            Bitmap bmp = new Bitmap(@"test.gif");
            int NumberOfLast = 0;
            for (int x = 0; x < bmp.Height; x++)
            {
                for (int y = 0; y < bmp.Width; y++)
                {
                    Color c = bmp.GetPixel(y, x);
                    bool flag = false;
                    for (int i = 0; i < NumberOfLast; i++)
                    {
                        if (c == masOfColor[i])
                            flag = true;
                    }
                    if (flag==false)
                    {
                        masOfColor[NumberOfLast] = c;
                        if (NumberOfLast<masOfColor.Length)
                        {
                            NumberOfLast++;
                        }                            
                    }
                }
            }
PM MAIL   Вверх
libman
Дата 26.6.2007, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 31.10.2006

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



Извеняюсь за опечатку в названии темы не Jig а Gif
PM MAIL   Вверх
stab
Дата 26.6.2007, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



всё намного проще: bmp.Palette.Entries.Length вернёт тебе кол-во цветов для индексированных битмапов. GIF как раз-таки индексированный формат.

Добавлено @ 00:06
после тестов стало ясно, что размер палитры для GIF всегда есть спенень двойки, даже если цветов меньше. вот решение:

Код

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace Vingrad.GifColorCount
{
    class Program
    {
        static void Main(string[] args)
        {
            Bitmap gif = new Bitmap(@"test.gif");
            Console.WriteLine("Color count: {0}", CountColors(gif));
            Console.WriteLine("Palette length: {0}", gif.Palette.Entries.Length);
            Console.ReadLine();
            gif.Dispose();
        }

        public static unsafe byte CountColors(Bitmap bitmap)
        {
            if (bitmap == null || bitmap.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new ArgumentException();
            }

            uint[] colorCounters = new uint[bitmap.Palette.Entries.Length];
            BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
            if (data != null)
            {
                byte* pixel = (byte*) data.Scan0;
                for (int y = 0; y < bitmap.Height; y++)
                {
                    for (int x = 0; x < bitmap.Width; x++)
                    {
                        colorCounters[pixel[x]]++;
                    }
                    pixel += data.Stride;
                }
                bitmap.UnlockBits(data);
            }

            byte result = 0;
            for (int i = 0; i < colorCounters.Length; i++)
            {
                if (colorCounters[i] != 0)
                {
                    result++;
                }
            }

            return result;
        }
    }
}


помимо всего прочего, пример можно адаптировать для подсчёта кол-ва вхождений определённого цвета, что уже делается, но не возвращается в качестве результата.

Добавлено @ 00:09
для проекта надо разрешить unsafe код: Project Properties -> Build -> Allow unsafe code


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
tol05
Дата 27.6.2007, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 63
Всего: 170



Хороший пример. 
cully, ты не мог бы прокомментировать его? Я в графике не силен, хотелось бы подъучиться... smile
в принципе, вот эту часть
Код

 for (int x = 0; x < bitmap.Width; x++)
{
    colorCounters[pixel[x]]++;
}
pixel += data.Stride;



--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
stab
Дата 27.6.2007, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



Цитата(tol05 @  27.6.2007,  21:13 Найти цитируемый пост)
colorCounters[pixel[x]]++;

битмап в формате 8bppIndexed, т.е. один пиксель - один байт, значение этого байта и используется для индексации в массиве счётчиков.

Цитата(tol05 @  27.6.2007,  21:13 Найти цитируемый пост)
pixel += data.Stride;

переход к следующему скану, data.Stride - обычно равно Width * (размер одного пикселя в байтах), но не всегда, т.к. может быть выравнивание или битмап может быть окном в другой битмап.


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
tol05
Дата 27.6.2007, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 63
Всего: 170



блин, полчаса пялился в твои строчки... И понял!!! 
Спасибо!  smile 


Круто, действительно круто...


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
libman
Дата 30.6.2007, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 31.10.2006

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



Огромое спасибо

Еще маленький вопрос. как сделать так что бы можно было определить на какой стадии находится выполнение. Т.е. как в методе который вы написали  public static unsafe byte CountColors(Bitmap bitmap), заставить двигаться полоску в компоненте progressBar который мы кинули на форму?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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