Pergunta

C # questão (NET 3.5). Eu tenho uma classe, ImageData, que tem um ushort campo [,] pixels. Estou lidando com formatos de imagem de propriedade. A classe ImageData leva um local de arquivo no construtor, em seguida, liga-se a extensão do arquivo para determinar como decodificar. Em vários dos arquivos de imagem, há um campo de "profundidade de bits" no cabeçalho. Após I descodificar o cabeçalho li os valores de pixel para a matriz de "pixels". Até agora eu não tive mais de 16 bpp, então eu estou bem. Mas o que se eu tiver 32bpp?

O que eu quero fazer é ter o tipo de pixels ser determinada em tempo de execução. Eu quero fazer isso depois que eu li a profundidade pouco fora do cabeçalho e antes de eu copiar os dados de pixel na memória. Alguma idéia?

Foi útil?

Solução

Para se resumem o seu problema, você quer ser capaz de ter uma classe que tem um ushort [,] pixels (16-bits por pixel), por vezes, e uma uint32 [, ] pixels de campo (32 bits por pixel) algumas outras vezes. Existem algumas maneiras diferentes para atingir este objectivo.

Você pode criar substitutos para ushort / uint32, fazendo uma classe Pixel com 32-bit e 16-bit sub-classes, substituindo vários operadores até o wazoo, mas isso incorre em muita sobrecarga, é complicado de acertar e até mesmo mais complicado para determinar se o seu direito. Como alternativa, você pode criar classes de proxy para a sua dados de pixel (que contêm o ushort [,] ou uint32 [,] matrizes e teria todos os assessores necessários para ser útil). A desvantagem não é que você provavelmente iria acabar com um monte de código caso especial na classe ImageData que executou uma forma ou de outra dependendo de alguma bandeira modo de 16-bit / 32-bit.

A melhor solução, eu acho, seria ImageData sub-classe em classes de 16 bits e 32 bits, e usar um método de fábrica para criar instâncias. Por exemplo. ImageData é a classe base, ImageData16bpp e ImageData32bpp são sub-classes, ImageData.Create método estático (cadeia ImageFileName) é o método de fabricação que cria quer ImageData16bpp ou ImageData32bpp acordo com os dados de cabeçalho. Por exemplo:

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;
}

Outras dicas

Eu diria para não fazer esse trabalho no construtor - Um construtor não deve fazer tanto trabalho, na minha opinião. Use um método de fábrica que lê o arquivo para determinar a profundidade de bits, em seguida, tê-lo construir a variante genérica correta da classe e devolvê-lo.

Tenha sua função de decodificação de retornar um objeto do tipo Array, que é a classe base de todas as matrizes. Então, as pessoas que se preocupam com o tipo pode fazer "se (a é ushort [,])" e assim por diante, se eles querem percorrer os pixels. Se você fazê-lo desta maneira, você precisa alocar a matriz em ImageData, e não o contrário.

Como alternativa, o chamador provavelmente sabe que tipo de matriz de pixels que quero que você uso. Mesmo que seja uma imagem 8bpp ou 16bpp, se você está decodificá-lo para uma tela de 32 bpp, você precisa usar uint em vez de ushort. Então, você poderia escrever uma função ImageData que irá decodificar em inteiros de qualquer tipo T é.

A raiz de seu problema é que você não sabe como decidir que tipo de formato de saída desejado. Você precisa descobrir isso primeiro, e a sintaxe programa vem em segundo lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top