Быстрый метод получения цвета пикселя?

Я работаю над плагином Photoshop, используя С# (с библиотекой объектов Adobe Photoshop). Я пытаюсь просмотреть все пиксели в моем активном документе, но с кодом, который у меня есть в настоящее время, требуется очень много времени даже для просмотра 1 строки пикселей в файле 256x256. Мне было интересно, может ли быть лучший (более быстрый) способ, чем использование ColorSampler для этого? (плагин С++?)

Вот что у меня сейчас есть: (http://forums.adobe.com/thread/290211) (С#, эквивалентный этому коду)

static void Main(string[] args)
{
    ps.Application app = new ps.Application();
    app.Preferences.RulerUnits = ps.PsUnits.psPixels; 

    ps.Document activeDoc = app.ActiveDocument;

    double docWidth = activeDoc.Width;
    double docHeight = activeDoc.Height;
    double xPos = 0.0D;
    double yPos = 0.0D;             

    activeDoc.ColorSamplers.RemoveAll();
    var pixelLoc = new object[] { 0.0D, 0.0D };
    ps.ColorSampler myColorSampler = activeDoc.ColorSamplers.Add(pixelLoc);

    var stopwatch = Stopwatch.StartNew();

    ps.SolidColor myColor;
    double red;
    double green;
    double blue;

    for (xPos = 0.0D; xPos <=docWidth - 1; xPos++)
    {
        myColor = myColorSampler.Color;
        red = myColor.RGB.Red;
        green = myColor.RGB.Green;
        blue = myColor.RGB.Blue;
        pixelLoc[0] = xPos;
        myColorSampler.Move(pixelLoc);
    }

    Console.WriteLine(stopwatch.ElapsedMilliseconds); //11000 ms for 1 row of 256 pixels


    Console.ReadLine();
}

person VincentC    schedule 20.11.2013    source источник
comment
Вы объявляете переменные в цикле for? Это может быть частью проблемы...   -  person Scott Solmer    schedule 21.11.2013
comment
Спасибо! Я переместил их из цикла for, и это немного ускорило его (11000 мс сейчас - 13000 мс раньше), я отредактировал свой исходный пост. Но все равно очень медленно...   -  person VincentC    schedule 21.11.2013
comment
Я бы предположил, что сам цикл довольно быстрый, поэтому внутри должно быть что-то, что заставляет его работать медленно - возможно, используйте секундомер для профилирования каждого вызова цвета. Я также заметил, что вы каждый раз вызываете myColor.RGB - имеет ли значение сохранение этого в переменной один раз? Вы также можете попробовать использовать Parallel.For для запуска цикла в многопоточном режиме :)   -  person GracelessROB    schedule 21.11.2013
comment
Спасибо! Я удалил все в цикле for, кроме myColorSampler.Move(pixelLoc); и это все еще занимает 11000 мс. Я думаю, это просто очень медленный метод? Я также попробовал многопоточную версию, и это значительно ускорило ее (сейчас 6500 мс), но это все еще очень медленно для всего 1 строки из 256 пикселей, не так ли? (Я хотел бы просмотреть растровые изображения 4096x4096 с помощью этого скрипта)   -  person VincentC    schedule 21.11.2013
comment
Может быть глупый вопрос, но есть ли способ преобразовать этот документ в простое изображение/растровое изображение .net? Потому что, если вы можете, люди могут помочь вам лучше.   -  person MindingData    schedule 21.11.2013


Ответы (1)


Я раньше не работал с этим API, но нашел этот сайт: Библиотека объектов Adobe Photoshop CS5 .

Я кое-что посмотрел и нашел метод SaveAs, который можно использовать для объекта Document. Вы можете использовать этот метод, чтобы сохранить документ как изображение (скажем, BITMAP).

Оттуда вы можете использовать несколько онлайн-источников, которые показывают, как быстро извлекать информацию о пикселях из BMP.

Вот одна конкретная статья: Работайте с растровыми изображениями быстрее в C#< /а>

Я понимаю, что не предоставляю вам код для копирования/вставки, но я надеюсь, что это укажет вам правильное направление.

person Jason    schedule 21.11.2013
comment
Спасибо! Я пробовал это, и я думаю, что это, вероятно, лучшее решение на данный момент. Для сохранения растрового файла размером 4096x4096 требуется всего ~100 мс! Мне просто интересно, знаете ли вы, есть ли способ пропустить часть записи на жесткий диск (могу ли я сохранить ее, например, в MemoryStream). Теперь мне нужно сначала сохранить его на жесткий диск, а затем прочитать обратно, возможно, этого можно избежать? - person VincentC; 22.11.2013
comment
Я рад, что это помогло. Кажется, что сохранение на диск является частью реализации SaveAs, поэтому, вероятно, нет никакого способа обойти это, если вы не найдете альтернативу использованию SaveAs. В идеале лучший способ — получить массив данных из активного документа за один вызов, но я просто не видел ничего подобного. - person Jason; 22.11.2013