Por que as imagens JPEG criada com System.Drawing maior do que os mapas de bits originais?
-
05-07-2019 - |
Pergunta
Estou tendo um problema estranho - Eu tenho cerca de 14,5 milhões de imagens bitmap, que são supostamente não compactado. Eu preciso converter esses bitmaps para JPG e armazená-los em um banco de dados.
Quando eu uso as classes fornecidas na biblioteca .NET System.Drawing para salvar o bitmap como um ImageFormat.Jpeg, o JPEG resultante é cerca de duas vezes o tamanho do bitmap original. Aqui está o código:
byte[] bitmapBytes = //get from the db
using(MemoryStream bitmapStream = new MemoryStream(bitmapBytes))
{
using(Bitmap bitmap = (Bitmap)Bitmap.FromStream(bitmapStream))
{
bitmap.Save("jpg.jpg", ImageFormat.Jpeg);
}
}
Eu olhei através do HEX de várias destas imagens, e parece que a configuração de compactação é "nenhum". Então, eu estou supondo que eles são descompactados. Além disso, o HEX para o arquivo original tem o código "BMP" e o arquivo resultante tem o código "JFIF" como seria de esperar.
As imagens são a preto e branco, sem cores.
Todos os pensamentos a respeito de porque este estaria acontecendo? Procurando por ponteiros na direção certa ...
Edições:
- Eu tentei usar a sobrecarga alternativa para salvar o que permite que você especifique a qualidade. Nenhum benefício visto.
- Eu também deveria especificar que eu sou o tipo de preso com JPEG até certo ponto aqui. Este é um sistema legado e outras partes do sistema de esperar JPEG.
atributos de imagem:
- dimensões de bitmap: 152x48
- tamanho de arquivo Bitmap: 1022 bytes
- JPEG: mesma dimensão
- tamanho JPEG: 2,2 kb
- info Bitmap: indexado, 1 camada (2 cores)
- resolução Bitmap: 96.012x 96,012 ppi
Solução
É provavelmente porque as imagens JPEG você está economizando agora são 24bit imagens de cores RGB, onde os bitmaps são 1 bpp preto e branco imagens.
Se os bitmaps são 1 bpp, jpeg provavelmente não é o melhor formato para convertê-los para.
Outras dicas
Black and White ou Greyscale?
A partir http://www.faqs.org/faqs /compression-faq/part2/section-6.html :
"JPEG funciona em ambos coloridas ou em escala de cinza imagens; ele não controla dois níveis imagens (em preto e branco), pelo menos não assim. Ele não lida com imagens colormapped qualquer um; você tem que pré-expandir aqueles em um não mapeada representação full-color. JPEG funciona melhor em imagens "tom contínuo". Imagens com muitos saltos bruscos em valores de cor não irá comprimir bem. "
Você precisa definir um atributo para o codificador para dizer que o nível de compressão para uso.
Veja também
Você vai querer passar a usar essa sobrecarga de Bitmap.Save , para que possa especificar o EncoderParameter .
Quanto ao porquê de seus arquivos estão ficando maiores, pode ser que o seu BMP foi executado comprimento codificado, ou usando uma (não de 24 bits) bitmap menor.
A comparação dos tamanhos para uma imagem de 2 cor 61x64:
- Fax-4 tiff: 268 bytes
- 2 BMP cor (como acima): 550 bytes
- 8 bit jpeg: 1502 bytes
- 32 bit jpeg (como System.Drawing faria criar): 2015 bytes
Então, se você tem que usar jpegs, convertê-los em 8 bits em primeiro lugar. Fazer isso na Net vai ser difícil, mas não há código de exemplo disponível no CodeProject e outros.
Apenas queria continuação com a minha solução. Eu era capaz de obter o resto do sistema para suportar formato PNG gráficos, então o que eu fiz foi converter os bitmaps em gráficos PNG, e torná-los um pouco por pixel preto e branco. Isso fez-los pequenos e eficientes.
Então, o problema era que JPGs Só não faça imagens algumas-cores também.
Confira aqui (How to: definir a compactação JPEG Nível) para alguma introspecção e exemplos , ImageCodecInfo e EncoderParameters são as chaves
Apenas um pensamento: você diz parte do seu sistema precisa os arquivos para ser arquivos JPEG. que é realmente verdadeiro ou ele só precisa os arquivos para ter a extensão JPG? Se assim for, você poderia - embora seja feio - basta renomear a extensão do arquivo, já que os arquivos BMP em seu caso são menores.
Por exemplo, no Windows, você pode tomar um arquivo BMP e alterar a extensão que seja para JPG, quando você abri-lo, o Windows não se importa e exibe-lo corretamente.
Este artigo kb deve mostrar-lhe como fazê-lo