\'http://tizzyt-archive.blogspot.com/2015/09/transparent-jpg.html
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public Class TransparentJPG
Private Shared ReadOnly _Magic() As Byte = {&H71, &H22, &H47, &H0}
Private Shared ReadOnly JMAGIC() As Byte = {&HFF, &HD8, &HFF, &HE0}
Private _Image As Bitmap
Public ReadOnly Property Width() As Integer
Get
Return _Image.Width
End Get
End Property
Public ReadOnly Property Height() As Integer
Get
Return _Image.Height
End Get
End Property
Public Shared Sub SaveTJPG(ByVal Path As String, ByRef Image As Bitmap, _
Optional Quality As Integer = 80, _
Optional Smoothing As Integer = 20, _
Optional ByVal Sampling As Integer = 0)
Dim RBitmap As New Bitmap(Image.Width, Image.Height * 2)
Dim G As Graphics = Graphics.FromImage(RBitmap)
G.DrawImage(Image, New Rectangle(0, 0, Image.Width, Image.Height))
G.DrawImage(Image, New Rectangle(0, Image.Height, Image.Width, Image.Height))
G.Dispose()
Dim bitmapData As BitmapData = RBitmap.LockBits(New Rectangle(0, 0, RBitmap.Width, RBitmap.Height), _
ImageLockMode.ReadWrite, RBitmap.PixelFormat)
Dim Iptr = bitmapData.Scan0
Dim Pixels(RBitmap.Width * RBitmap.Height * 4 - 1) As Byte
Marshal.Copy(Iptr, Pixels, 0, Pixels.Length)
Dim AlphaPos As Integer = 3
For i = Pixels.Length / 2 To Pixels.Length - 1 Step 4
Dim A As Byte = Pixels(AlphaPos)
Pixels(AlphaPos) = 255
Pixels(i) = A
Pixels(i + 1) = A
Pixels(i + 2) = A
Pixels(i + 3) = 255
AlphaPos += 4
Next
Marshal.Copy(Pixels, 0, Iptr, Pixels.Length)
RBitmap.UnlockBits(bitmapData)
Using ms As New MemoryStream
Dim SJPG As New JpegImage(RBitmap)
Dim P As New CompressionParameters
Select Case Sampling
Case 0 : P.Subsampling = Subsampling.LowDetail_4_1_1
Case 2 : P.Subsampling = Subsampling.HighDetail_4_4_4
Case Else : P.Subsampling = Subsampling.MediumDetail_4_2_2
End Select
P.Quality = Quality
P.SimpleProgressive = True
P.SmoothingFactor = Smoothing
RBitmap.Dispose()
SJPG.WriteJpeg(ms, P)
Dim Data() As Byte = ms.GetBuffer.Skip(10).ToArray
Using fs As New FileStream(Path, FileMode.Create)
fs.Write(_Magic, 0, _Magic.Length)
fs.Write(Data, 0, Data.Length)
fs.Flush()
fs.Close()
End Using
End Using
End Sub
Public Sub New(ByVal Path As String)
Dim SourceData() As Byte = System.IO.File.ReadAllBytes(Path)
For i = 0 To 3
SourceData(i) = JMAGIC(i)
Next
Dim MainBM As Image
Using ms As New MemoryStream(SourceData)
MainBM = Image.FromStream(ms)
ms.Close()
End Using
Dim HalfHeight As Integer = MainBM.Height / 2
Using Colors As New Bitmap(MainBM.Width, HalfHeight)
Using Alphas As New Bitmap(MainBM.Width, HalfHeight)
Dim PixelCount As Integer = Colors.Width * Colors.Height * 4 - 1
Dim G As Graphics = Graphics.FromImage(Colors)
G.DrawImage(MainBM, New Rectangle(0, 0, MainBM.Width, MainBM.Height))
G = Graphics.FromImage(Alphas)
G.DrawImage(MainBM, New Rectangle(0, 0 - HalfHeight, MainBM.Width, MainBM.Height))
G.Dispose()
MainBM.Dispose()
Dim ColorbitmapData As BitmapData = _
Colors.LockBits(New Rectangle(0, 0, Colors.Width, Colors.Height), _
ImageLockMode.ReadWrite, Colors.PixelFormat)
Dim ColorPixels(PixelCount) As Byte
Dim ColorIptr As IntPtr = ColorbitmapData.Scan0
Marshal.Copy(ColorIptr, ColorPixels, 0, ColorPixels.Length)
Dim AlphaDepth As Integer = System.Drawing.Bitmap.GetPixelFormatSize(Alphas.PixelFormat)
Dim AlphabitmapData As BitmapData = _
Alphas.LockBits(New Rectangle(0, 0, Alphas.Width, Alphas.Height), _
ImageLockMode.ReadWrite, Alphas.PixelFormat)
Dim AlphaPixels(PixelCount) As Byte
Dim AlphaIptr As IntPtr = AlphabitmapData.Scan0
Marshal.Copy(AlphaIptr, AlphaPixels, 0, AlphaPixels.Length)
For i = 0 To AlphaPixels.Length - 1 Step 4
Dim A As Single = AlphaPixels(i)
A += AlphaPixels(i + 1)
A += AlphaPixels(i + 2)
ColorPixels(i + 3) = Math.Round(A / 3)
Next
Marshal.Copy(ColorPixels, 0, ColorIptr, ColorPixels.Length)
Marshal.Copy(AlphaPixels, 0, AlphaIptr, AlphaPixels.Length)
Colors.UnlockBits(ColorbitmapData)
Alphas.UnlockBits(AlphabitmapData)
Alphas.Dispose()
_Image = Colors.Clone
Colors.Dispose()
End Using
End Using
End Sub
Public Shared Sub Decode(ByVal Data() As Byte, _
ByRef Pixels() As Byte, ByRef Width As Integer, ByRef Height As Integer)
For i = 0 To 3
Data(i) = JMAGIC(i)
Next
Dim MainBM As Image
Using ms As New MemoryStream(Data)
MainBM = Image.FromStream(ms)
ms.Close()
End Using
Dim HalfHeight As Integer = MainBM.Height / 2
Using Colors As New Bitmap(MainBM.Width, HalfHeight)
Using Alphas As New Bitmap(MainBM.Width, HalfHeight)
Dim PixelCount As Integer = Colors.Width * Colors.Height * 4 - 1
Dim G As Graphics = Graphics.FromImage(Colors)
G.DrawImage(MainBM, New Rectangle(0, 0, MainBM.Width, MainBM.Height))
G = Graphics.FromImage(Alphas)
G.DrawImage(MainBM, New Rectangle(0, 0 - HalfHeight, MainBM.Width, MainBM.Height))
G.Dispose()
MainBM.Dispose()
Dim ColorbitmapData As BitmapData = _
Colors.LockBits(New Rectangle(0, 0, Colors.Width, Colors.Height), _
ImageLockMode.ReadWrite, Colors.PixelFormat)
Dim ColorPixels(PixelCount) As Byte
Dim ColorIptr As IntPtr = ColorbitmapData.Scan0
Marshal.Copy(ColorIptr, ColorPixels, 0, ColorPixels.Length)
Dim AlphaDepth As Integer = System.Drawing.Bitmap.GetPixelFormatSize(Alphas.PixelFormat)
Dim AlphabitmapData As BitmapData = _
Alphas.LockBits(New Rectangle(0, 0, Alphas.Width, Alphas.Height), _
ImageLockMode.ReadWrite, Alphas.PixelFormat)
Dim AlphaPixels(PixelCount) As Byte
Dim AlphaIptr As IntPtr = AlphabitmapData.Scan0
Marshal.Copy(AlphaIptr, AlphaPixels, 0, AlphaPixels.Length)
For i = 0 To AlphaPixels.Length - 1 Step 4
Dim A As Single = AlphaPixels(i)
A += AlphaPixels(i + 1)
A += AlphaPixels(i + 2)
ColorPixels(i + 3) = Math.Round(A / 3)
Next
Marshal.Copy(ColorPixels, 0, ColorIptr, ColorPixels.Length)
Marshal.Copy(AlphaPixels, 0, AlphaIptr, AlphaPixels.Length)
Colors.UnlockBits(ColorbitmapData)
Alphas.UnlockBits(AlphabitmapData)
Pixels = ColorPixels
Width = Colors.Width
Height = Colors.Height
Colors.Dispose()
Alphas.Dispose()
End Using
End Using
End Sub
Public Shared Function LoadTJPG(ByVal Path As String) As Bitmap
Dim SourceData() As Byte = System.IO.File.ReadAllBytes(Path)
For i = 0 To 3
SourceData(i) = JMAGIC(i)
Next
Dim MainBM As Image
Using ms As New MemoryStream(SourceData)
MainBM = Image.FromStream(ms)
ms.Close()
End Using
Dim HalfHeight As Integer = MainBM.Height / 2
Using Colors As New Bitmap(MainBM.Width, HalfHeight)
Using Alphas As New Bitmap(MainBM.Width, HalfHeight)
Dim PixelCount As Integer = Colors.Width * Colors.Height * 4 - 1
Dim G As Graphics = Graphics.FromImage(Colors)
G.DrawImage(MainBM, New Rectangle(0, 0, MainBM.Width, MainBM.Height))
G = Graphics.FromImage(Alphas)
G.DrawImage(MainBM, New Rectangle(0, 0 - HalfHeight, MainBM.Width, MainBM.Height))
G.Dispose()
MainBM.Dispose()
Dim ColorbitmapData As BitmapData = _
Colors.LockBits(New Rectangle(0, 0, Colors.Width, Colors.Height), _
ImageLockMode.ReadWrite, Colors.PixelFormat)
Dim ColorPixels(PixelCount) As Byte
Dim ColorIptr As IntPtr = ColorbitmapData.Scan0
Marshal.Copy(ColorIptr, ColorPixels, 0, ColorPixels.Length)
Dim AlphaDepth As Integer = System.Drawing.Bitmap.GetPixelFormatSize(Alphas.PixelFormat)
Dim AlphabitmapData As BitmapData = _
Alphas.LockBits(New Rectangle(0, 0, Alphas.Width, Alphas.Height), _
ImageLockMode.ReadWrite, Alphas.PixelFormat)
Dim AlphaPixels(PixelCount) As Byte
Dim AlphaIptr As IntPtr = AlphabitmapData.Scan0
Marshal.Copy(AlphaIptr, AlphaPixels, 0, AlphaPixels.Length)
For i = 0 To AlphaPixels.Length - 1 Step 4
Dim A As Single = AlphaPixels(i)
A += AlphaPixels(i + 1)
A += AlphaPixels(i + 2)
ColorPixels(i + 3) = Math.Round(A / 3)
Next
Marshal.Copy(ColorPixels, 0, ColorIptr, ColorPixels.Length)
Marshal.Copy(AlphaPixels, 0, AlphaIptr, AlphaPixels.Length)
Colors.UnlockBits(ColorbitmapData)
Alphas.UnlockBits(AlphabitmapData)
Alphas.Dispose()
LoadTJPG = Colors.Clone
Colors.Dispose()
End Using
End Using
End Function
Public Shared Widening Operator CType(ByVal TJPG As TransparentJPG) As Bitmap
Return TJPG._Image
End Operator
Public ReadOnly Property ImageStream() As Stream
Get
Dim ms As New MemoryStream
_Image.Save(ms, Drawing.Imaging.ImageFormat.Png)
ms.Flush()
Return ms
End Get
End Property
Public Sub Dispose()
_Image.Dispose()
End Sub
End Class