Вопрос

Вопрос по C # (.net 3.5).У меня есть класс ImageData, в котором есть поле ushort[,] пикселей.Я имею дело с проприетарными форматами изображений.Класс ImageData принимает местоположение файла в конструкторе, затем включает расширение файла, чтобы определить способ декодирования.В нескольких файлах изображений в заголовке есть поле "разрядность".После того, как я декодирую заголовок, я считываю значения пикселей в массив "pixels".До сих пор у меня было не более 16 бпп, так что я в порядке.Но что, если у меня 32 бит /с?

Что я хочу сделать, так это определить тип пикселей во время выполнения.Я хочу сделать это после того, как я считаю разрядность из заголовка и перед копированием пиксельных данных в память.Есть какие-нибудь идеи?

Это было полезно?

Решение

Чтобы свести к минимуму вашу проблему, вы хотите иметь возможность иметь класс, который имеет ushort[,] пикселей поле (16 бит на пиксель) иногда и uint32[,] пикселей поле (32 бита на пиксель) в других случаях.Есть несколько различных способов достичь этого.

Вы могли бы создать замены для ushort / uint32, создав класс Pixel с 32-разрядными и 16-разрядными подклассами, переопределяя различные операторы в wazoo, но это сопряжено с большими накладными расходами, сложно разобраться и еще сложнее определить, правильно ли это.В качестве альтернативы вы могли бы создать прокси-классы для ваших пиксельных данных (которые содержали бы массивы ushort [,] или uint32 [,] и имели бы все необходимые средства доступа, чтобы быть полезными).Недостатком является то, что вы, вероятно, в конечном итоге получите много кода особого случая в классе ImageData, который выполняется тем или иным способом в зависимости от некоторого флага 16-разрядного / 32-разрядного режима.

Я думаю, лучшим решением было бы разделить ImageData на 16-разрядные и 32-разрядные классы и использовать фабричный метод для создания экземпляров.Например.ImageData - это базовый класс, ImageData16bpp и ImageData32bpp - это подклассы статического метода ImageData.Create(string imageFilename) - это заводской метод, который создает либо ImageData16bpp, либо ImageData32bpp в зависимости от данных заголовка.Например:

public static ImageData Create(string imageFilename)
{
   // ...
   ImageDataHeader imageHeader = ParseHeader(imageFilename);
   ImageData newImageData;
   if (imageHeader.bpp == 32)
   {
      newImageData = new ImageData32(imageFilename, imageHeader);
   }
   else
   {
      newImageData = new ImageData16(imageFilename, imageHeader);
   }
   // ...
   return newImageData;
}

Другие советы

Я бы посоветовал не выполнять эту работу в конструкторе - на мой взгляд, конструктор не должен выполнять так много работы.Используйте фабричный метод, который считывает файл для определения разрядности, затем попросите его создать правильный универсальный вариант класса и вернуть его.

Попросите вашу функцию decode вернуть объект типа Array, который является базовым классом всех массивов.Тогда люди, которым важен тип, могут сделать "if (a is ushort[,])" и так далее, если они хотят просмотреть пиксели.Если вы сделаете это таким образом, вам нужно выделить массив в ImageData, а не наоборот.

В качестве альтернативы, вызывающий, вероятно, знает, что это за массив пикселей они хочу, чтобы вы использовали.Даже если это изображение с частотой 8 или 16 бит /с, если вы декодируете его на экран с частотой 32 бит / с, вам нужно использовать uint вместо ushort.Таким образом, вы могли бы написать функцию ImageData, которая будет декодировать в целые числа любого типа T .

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top