So, der folgende Code macht genau das, was ich zu Beginn wollte. Er basiert auf diesen Methoden http://www.vbarchiv.net/workshop/details.php?id=100
Leider konnte ich keinen Weg finden, wie ich das Pixelformat verlustarm von Format32bppArgb zu Format8bppIndexed ändern kann. Deswegen bin ich für .gif-Dateien den Umweg über die BitmapEncoder/BitmapDecoder gegangen, die das bestmögliche Ergebnis erzielen (den Code dafür habe ich ausgeklammert, da zu lang).
Wenn jemand einen guten Weg kennt das Pixelformat in VB.net (nicht c#) zu ändern, der melde sich bitte jetzt Alle gefunden Lösungen arbeiten mit Pointern und ich weiß nicht so recht, wie ein ähnliches Konstrukt in VB.net aussieht.
Imports System.IO
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public Class MeineKlasse
Public Enum SupportedFormat
PNG
GIF
JPEG
TIFF
BMP
End Enum
Public Shared Function ChangeAlphaToWhiteBackground(ByVal Bilddatei_in As _
Stream, ByVal Format As SupportedFormat) As MemoryStream
Dim output As New MemoryStream()
Dim bmp_in As New Bitmap(Bilddatei_in)
Dim bmp_rect As New Rectangle(0, 0, bmp_in.Width, bmp_in.Height)
Dim bmp = bmp_in.Clone(bmp_rect, bmp_in.PixelFormat)
If Format.ToString.ToUpper <> "GIF" Then
If (bmp.PixelFormat = PixelFormat.Format8bppIndexed) OrElse ( _
bmp_in.PixelFormat = PixelFormat.Format32bppArgb) OrElse ( _
bmp_in.PixelFormat = PixelFormat.Format64bppArgb) Then
Debug.Print(bmp_in.PixelFormat.ToString)
Dim bpp As Integer = Image.GetPixelFormatSize(bmp_in.PixelFormat) / _
8
Dim Byte_Index As Integer = -bpp
Dim bmp_data As BitmapData = bmp.LockBits(bmp_rect, _
ImageLockMode.ReadWrite, _
bmp_in.PixelFormat)
Dim bmp_ptr As IntPtr = bmp_data.Scan0
Dim bmp_bytes As Integer = bmp.Width * bmp.Height * bpp
Dim bmp_array(bmp_bytes - 1) As Byte
Runtime.InteropServices.Marshal.Copy(bmp_ptr, bmp_array, 0, _
bmp_bytes)
For y = 1 To bmp.Height
For x = 1 To bmp.Width
Byte_Index += bpp
'True, falls ein transparentes Pixel vorliegt
If bmp_array(Byte_Index + bpp - 1) = 0 Then
For i = 0 To bpp - 2
'Ändert die RGB Werte des Pixels zu 255,255,255
bmp_array(Byte_Index + i) = 255
Next
End If
Next x
Next y
Runtime.InteropServices.Marshal.Copy(bmp_array, 0, bmp_ptr, _
bmp_bytes)
bmp.UnlockBits(bmp_data)
End If
Dim EncoderParameters As New EncoderParameters(2)
EncoderParameters.Param(0) = New EncoderParameter(Encoder.Quality, _
CType(100, Int32))
EncoderParameters.Param(1) = New EncoderParameter(Encoder.Compression, _
Fix(EncoderValue.CompressionNone))
bmp.Save(output, EncoderInfo(Format.ToString), EncoderParameters)
Else '--------------------------GIF---------------------------------------
End If
bmp.Dispose() : bmp_in.Dispose()
Return output
End Function
' Formatdescriptoren: BMP JPEG GIF TIFF PNG
Private Shared Function EncoderInfo(ByVal FormatDescriptor As String) As _
ImageCodecInfo
Dim encoders() As ImageCodecInfo = ImageCodecInfo.GetImageEncoders()
FormatDescriptor = Trim(UCase(FormatDescriptor))
Dim i As Integer = 0
While i < encoders.Length
If UCase(encoders(i).FormatDescription) = FormatDescriptor Then
Return encoders(i)
End If
i += 1
End While
Return Nothing
End Function
End Class
Beitrag wurde zuletzt am 16.05.12 um 12:13:50 editiert. |