C # «общая» проблема типа - PullRequest
2 голосов
/ 19 сентября 2008

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

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

Ответы [ 3 ]

2 голосов
/ 19 сентября 2008

Чтобы свести к минимуму вашу проблему, вы хотите иметь класс, который иногда имеет поле 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;
}
2 голосов
/ 19 сентября 2008

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

0 голосов
/ 19 сентября 2008

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...