profundidad online imagenes grafico entre diseño diferencia cuál color cambiar c# vb.net bitmap imaging

c# - online - profundidad de color 8 16 o 32 bits



¿Generar archivo de imagen con poca profundidad de bits? (5)

bpp = bits por píxel, entonces 32bpp significa 8/8/8/8 para R / G / B / A.

Al igual que .NET tiene una enumeración para estos "System.Drawing.Imaging.PixelFormat".

Ahora, una vez que tengo un objeto Bitmap o Image con mis gráficos, ¿cómo lo guardaría en un archivo / qué formato usaría?

¿Qué formato de archivo de imagen (JPEG / GIF / PNG) admite baja profundidad de bits como 16bpp o 8bpp (en lugar de 32bpp o 24bpp habituales)?


Código no probado

Image myImage = new Image(); EncoderParameters parameters = new EncoderParameters(1); parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8); myImage.Save(somestream, ImageFormat.Png, parameters);

Mire el espacio de nombres System.Drawing.Imaging y juegue con los ajustes del parámetro Encoder.xxx y la imagen. Guarde el método. HTH.

Actualización también vale la pena señalar que si desea una imagen pequeña (bajo conteo de bytes) puede intentar guardar como JPEG y utilizando Encoder.Compression compresión pero a un costo de calidad de imagen.


Prueba esto:

ImageCodecInfo pngCodec = ImageCodecInfo.GetImageEncoders().Where(codec => codec.FormatID.Equals(ImageFormat.Png.Guid)).FirstOrDefault(); if (pngCodec != null) { EncoderParameters parameters = new EncoderParameters(); parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8); myImage.Save(myStream, pngCodec, parameters); }


Todos los formatos de imagen admiten efectivamente profundidades de bits bajas. Simplemente deja los últimos bits sin usar, si no es necesario. GIF solo admite color oscuro; estás restringido a 256 colores.


No creo que la respuesta del otro haya probado su código, ya que GDI + PNG no es compatible con Encoder.BitDepth EncoderParameter. De hecho, el único códec que lo hace es TIFF.

Debes cambiar el PixelFormat de tu imagen antes de guardar para que la salida tenga efecto. Esto no siempre producirá el PixelFormat que esperas. Ver mi publicación aquí para obtener más información sobre qué PixelFormats se convierten en qué.

En cuanto a las conversiones de PixelFormat, algo como lo siguiente funcionará:

private Bitmap ChangePixelFormat(Bitmap inputImage, PixelFormat newFormat) { Bitmap bmp = new Bitmap(inputImage.Width, inputImage.Height, newFormat); using (Graphics g = Graphics.FromImage(bmp)) { g.DrawImage(inputImage, 0, 0); } return bmp; }

Desafortunadamente, estas conversiones pueden producir resultados realmente malos. Esto es especialmente cierto en el caso en que está realizando una conversión con pérdida (alta profundidad de bits a menor).


Un bit por píxel

Esto produce el PNG más pequeño posible de .Net solamente. Tenga en cuenta que es b & w, ni siquiera en escala de grises. Útil para documentos.

Código de consumidor:

Dim src = (the original bitmap) Using img = New Bitmap(src.Width, src.Height, PixelFormat.Format16bppRgb555) '' Provided Make1bpp function requires this img.SetResolution(src.HorizontalResolution, src.VerticalResolution) Using g = Graphics.FromImage(img) g.Clear(Color.White) '' remove transparancy g.DrawImage(src, 0, 0, src.Width, src.Height) End Using Using img2 As Bitmap = Make1bpp(img) img2.SetResolution(src.HorizontalResolution, src.VerticalResolution) Dim myencoder = (From parm In ImageCodecInfo.GetImageEncoders() Where parm.MimeType = "image/png").First() Dim encoderParams = New EncoderParameters(1) encoderParams.Param(0) = New EncoderParameter(Encoder.ColorDepth, 8L) If IO.File.Exists(pngName) Then IO.File.Delete(pngName) End If img2.Save(pngName, myencoder, encoderParams) End Using End Using

Make1bpp

Esto es lo que le importa al codificador PNG

Function Make1bpp(ByVal bmpIN As Bitmap) As Bitmap Dim bmpOUT As Bitmap bmpOUT = NewBitmap(bmpIN.Width, bmpIN.Height, PixelFormat.Format1bppIndexed) bmpOUT.SetResolution(bmpIN.HorizontalResolution, bmpIN.VerticalResolution) '' seems like I''ve got this crap in this program about 100x. If bmpIN.PixelFormat <> PixelFormat.Format16bppRgb555 Then Throw New ApplicationException("hand-coded routine can only understand image format of Format16bppRgb555 but this image is " & _ bmpIN.PixelFormat.ToString & ". Either change the format or code this sub to handle that format, too.") End If '' lock image bytes Dim bmdIN As BitmapData = bmpIN.LockBits(New Rectangle(0, 0, bmpIN.Width, bmpIN.Height), _ Imaging.ImageLockMode.ReadWrite, bmpIN.PixelFormat) '' lock image bytes Dim bmdOUT As BitmapData = bmpOUT.LockBits(New Rectangle(0, 0, bmpOUT.Width, bmpOUT.Height), _ Imaging.ImageLockMode.ReadWrite, bmpOUT.PixelFormat) '' Allocate room for the data. Dim bytesIN(bmdIN.Stride * bmdIN.Height) As Byte Dim bytesOUT(bmdOUT.Stride * bmdOUT.Height) As Byte '' Copy the data into the PixBytes array. Marshal.Copy(bmdIN.Scan0, bytesIN, 0, CInt(bmdIN.Stride * bmpIN.Height)) '' > this val = white pix. (each of the 3 pix in the rgb555 can hold 32 levels... 2^5 huh.) Dim bThresh As Byte = CByte((32 * 3) * 0.66) '' transfer the pixels For y As Integer = 0 To bmpIN.Height - 1 Dim outpos As Integer = y * bmdOUT.Stride Dim instart As Integer = y * bmdIN.Stride Dim byteval As Byte = 0 Dim bitpos As Byte = 128 Dim pixval As Integer Dim pixgraylevel As Integer For inpos As Integer = instart To instart + bmdIN.Stride - 1 Step 2 pixval = 256 * bytesIN(inpos + 1) + bytesIN(inpos) '' DEPENDANT ON Format16bppRgb555 pixgraylevel = ((pixval) And 31) + ((pixval >> 5) And 31) + ((pixval >> 10) And 31) If pixgraylevel > bThresh Then '' DEPENDANT ON Format16bppRgb555 byteval = byteval Or bitpos End If bitpos = bitpos >> 1 If bitpos = 0 Then bytesOUT(outpos) = byteval byteval = 0 bitpos = 128 outpos += 1 End If Next If bitpos <> 0 Then '' stick a fork in any unfinished busines. bytesOUT(outpos) = byteval End If Next '' unlock image bytes '' Copy the data back into the bitmap. Marshal.Copy(bytesOUT, 0, _ bmdOUT.Scan0, bmdOUT.Stride * bmdOUT.Height) '' Unlock the bitmap. bmpIN.UnlockBits(bmdIN) bmpOUT.UnlockBits(bmdOUT) '' futile attempt to free memory. ReDim bytesIN(0) ReDim bytesOUT(0) '' return new bmp. Return bmpOUT End Function