W
Willdoe
Guest
Consider the code that follows, the problem I am having is that when I add a gif with transparency already instead of clearing the image and redrawing it just draws on top of what has already been rendered. I think it has something to do with the writeGraphicCtrlExt() sub routine, but I am not sure. Any help would be just great,
Public Class AnimatedGif
Protected width As Integer
Protected height As Integer
Protected transparent As Color
Protected transIndex As Integer ; // transparent index in color table
Protected repeat As Integer = -1 ; // no repeat
Protected delay As Integer = 0 ; // frame delay (hundredths)
Protected started As Boolean = False ; // ready to output frames
Protected out As IO.FileStream
Protected MyOut As IO.FileStream
Protected image1 As Image ; // current frame
Protected pixels() As Byte ; // BGR byte array from frame
Protected indexedPixels() As Byte ; // converted frame indexed to palette
Protected colorDepth As Integer ; // number of bit planes
Protected colorTab() As Byte ; // RGB palette
Protected usedEntry(256) As Boolean = new boolean[256]; // active palette entries
Protected palSize As Integer = 7 ; // color table size (bits-1)
Protected dispose As Integer = -1 ; // disposal code (-1 = use default)
Protected closeStream As Boolean = False ; // close stream when finished
Protected firstFrame As Boolean = True ;
Protected sizeSet As Boolean = False ; // if false, get size from first frame
Protected sample As Integer = 10 ; // default sample interval for quantizer
Public Sub setDelay(ByVal ms As Integer)
delay = Math.Round(ms / 10.0F)
End Sub
Public Sub setDispose(ByVal code As Integer)
If code >= 0 Then
dispose = code
End If
End Sub
Public Sub setRepeat(ByVal iter As Integer)
If iter >= 0 Then
repeat = iter
End If
End Sub
Public Sub setTransparent(ByVal c As Color)
transparent = c
End Sub
Protected Function findClosest(ByVal c As Color) As Int16
End Function
Dim colorpal As Drawing.Imaging.ColorPalette
Public Function addFrame(ByVal im As Image) As Boolean
If IsNothing(im) Or started = False Then
MsgBox("Error Loading Image", MsgBoxStyle.Critical, "Error")
Return False
End If
Dim ok As Boolean = True
Try
If sizeSet = False Then
// use first frames size
setSize(im.Width, im.Height)
image1 = im.Clone
Else
If im.Width <> width Or im.Height <> height Then
Dim G = Graphics.FromImage(image1)
G.DrawImage(im, 0, 0, image1.Width, image1.Height)
G.Dispose()
End If
End If
getImagePixels() // convert to correct format if necessary
analyzePixels() // build color table & map pixels
colorpal = image1.Palette
If firstFrame = True Then
writeLSD() // logical screen descriptior
out.Flush()
writePalette() // global color table
If (repeat >= 0) Then
// use NS app extension to indicate reps
writeNetscapeExt()
End If
Else
End If
writeres()
writeGraphicCtrlExt() ; // write graphic control extension
writeImageDesc() ; \// image descriptor
If firstFrame = False Then ) {
writePalette()
End If
writePixels() // encode and write pixel data
firstFrame = False
Catch
ok = False
End Try
Return ok
End Function
Public Function finish() As Boolean
If started = False Then Return False
Dim ok As Boolean = True
started = False
Try
out.WriteByte(&H3B) ; // gif trailer
out.Flush() ;
If (closeStream = True) Then
out.Close()
out.Dispose()
image1.Dispose()
End If
Catch
ok = False
End Try
// reset for subsequent use
transIndex = 0 ;
out = Nothing
image1 = Nothing
ReDim pixels(0)
ReDim indexedPixels(0)
ReDim colorTab(0)
closeStream = False
firstFrame = True
Return ok
End Function
/**
* Sets frame rate in frames per second. Equivalent to
*
.
*
* @param fps float frame rate (frames per second)
*/
Public Sub setFrameRate(ByVal fps As Single)
If fps <> 0 Then
delay = Math.Round(100.0F / fps)
End If
End Sub
/**
* Sets quality of color quantization (conversion of images
* to the maximum 256 colors allowed by the GIF specification).
* Lower values (minimum = 1) produce better colors, but slow
* processing significantly. 10 is the default, and produces
* good color mapping at reasonable speeds. Values greater
* than 20 do not yield significant improvements in speed.
*
* @param quality int greater than 0.
* @return
*/
Public Sub setQuality(ByVal quality As Integer)
If quality < 1 Then quality = 1
sample = quality
End Sub
/**
* Sets the GIF frame size. The default size is the
* size of the first frame added if this method is
* not invoked.
*
* @param w int frame width.
* @param h int frame width.
*/
Public Sub setSize(ByVal w As Integer, ByVal h As Integer)
If started = True And firstFrame = False Then Exit Sub
width = w
height = h
If (width < 1) Then width = 320
If (height < 1) Then height = 240
sizeSet = True
End Sub
/**
* Initiates GIF file creation on the given stream. The stream
* is not closed automatically.
*
* @param os OutputStream on which GIF images are written.
* @return false if initial write failed.
*/
Public Overloads Function start(ByRef os As IO.FileStream) As Boolean
If IsNothing(os) Then Return False
Dim ok As Boolean = True
closeStream = False
out = os
Try
writeString("GIF89a") ; // header
Catch
ok = False
End Try
started = ok
Return started
End Function
/**
* Initiates writing of a GIF file with the specified name.
*
* @param file String containing output file name.
* @return false if open or initial write failed.
*/
Dim outputstream As System.IO.StreamWriter
Public Overloads Function start(ByVal file As String)
Dim ok As Boolean = True
Try
outputstream = New System.IO.StreamWriter(file)
Try
out.Dispose()
Catch
End Try
out = New IO.FileStream(file, IO.FileMode.Create)
ok = start(out)
closeStream = True
Catch
ok = False
End Try
started = ok
Return started
End Function
/**
* Analyzes image colors and creates color map.
*/
/**
* Returns index of palette color closest to c
*
*/
/**
* Extracts image pixels into byte array "pixels"
*/
Protected Sub getImagePixels()
Dim w As Integer = image1.Width()
Dim h As Integer = image1.Height()
Dim thetype As Integer = image1.GetType
If w <> width Or h <> height Then
image1 = New Bitmap(width, height)
End If
if ((w != width)
|| (h != height)
|| (type != BufferedImage.TYPE_3BYTE_BGR)) {
// create new image with right size/format
dim temp as Image = new Bitmap(width,height,
new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = temp.createGraphics();
g.drawImage(image, 0, 0, null);
image = temp;
}
colorpal.
For x As Int16 = 0 To pixels.Count - 1
Console.WriteLine(x & ":" & Hex(x) & ":" & Hex(pixels(x)) & " : " & CStr(x))
Next
Try
Array.Clear(pixels, 0, pixels.Length)
Catch
End Try
ReDim pixels(0)
Dim mem As New IO.MemoryStream
image1.Save(mem, System.Drawing.Imaging.ImageFormat.Gif)
pixels = mem.ToArray
colorpal = image1.Palette.Entries
End Sub
/**
* Writes Graphic Control Extension
*/
Protected Sub writeGraphicCtrlExt()
Dim transp As Integer, disp As Integer
If transparent = Nothing Then
transp = 0
disp = 0 // dispose = no action
Else
transp = 1
disp = 2 ; // force clear if using transparent color
End If
If (dispose >= 0) Then
disp = dispose & 7 ; // user override
End If
disp <<= 2
out.WriteByte(0)
out.WriteByte(&H21) ; // extension introducer
out.WriteByte(&HF9) ; // GCE label
out.WriteByte(&H4) ; // data block size
out.WriteByte(&H4)
// packed fields
out.WriteByte(0 Or 2 Or 0 Or 1) // 1:3 reserved
out.WriteByte(&H1)
disp | // 4:6 disposal
0 | // 7 user input - 0 = none
transp); // 8 transparency flag
writeShort(delay)
56) ; // delay x 1/100 sec
out.WriteByte(pixels(787)) ; // transparent color index
out.WriteByte(0) ; // block terminator
out.Flush()
End Sub
/**
* Writes Image Descriptor
*/
Protected Sub writeImageDesc()
Exit Sub
out.WriteByte(&H2C) ; // image separator
writeShort(0) ; // image position x,y = 0,0
writeShort(0) ;
writeShort(width) ; // image size
writeShort(height) ;
// packed fields
firstFrame = False
If firstFrame = True Then
// no LCT - GCT is used for first (or only) frame
out.WriteByte(0)
Else
// specify normal LCT
out.WriteByte(&H80 Or 0 Or 0 Or 0 Or palSize) // 1 local color table 1=yes
0 | // 2 interlace - 0=no
0 | // 3 sorted - 0=no
0 | // 4-5 reserved
palSize); // 6-8 size of color table
End If
End Sub
/**
* Writes Logical Screen Descriptor
*/
Protected Sub writeLSD() throws IOException {
// logical screen size
out.Flush()
writeShort(width)
writeShort(height)
// packed fields
out.WriteByte(&H80 Or &H70 Or &H0 Or palSize) | // 1 : global color table flag = 1 (gct used)
0x70 | // 2-4 : color resolution = 7
0x00 | // 5 : gct sort flag = 0
palSize)); // 6-8 : gct size
out.WriteByte(0) ; // background color index
out.WriteByte(0) ; // pixel aspect ratio - assume 1:1
out.Write(pixels, 0, 12)
End Sub
/**
* Writes Netscape application extension to define
* repeat count.
*/
Dim NetOffSet As Integer = 0
Protected Sub writeNetscapeExt() throws IOException {
out.WriteByte(&H21) ; // extension introducer
out.WriteByte(&HFF) ; // app extension label
out.WriteByte(11) ; // block size
writeString("NETSCAPE" & "2.0") ; // app id + auth code
out.WriteByte(3) ; // sub-block size
out.WriteByte(1) ; // loop sub-block id
writeShort(repeat) ; // loop count (extra iterations, 0=repeat forever)
out.WriteByte(0) ; // block terminator
NetOffSet = 19
End Sub
/**
* Writes color table
Dim ColorBytes(767) As Byte
Protected Sub writePalette() throws IOException {
out.Write(colorTab, 0, colorTab.Length - 1) , 0, colorTab.Length)
Dim J As Integer = 0
For a As Int16 = 0 To colorpal.Entries.Length - 1
TheColor = colorpal.Entries(a)
ColorBytes(J) = TheColor.R
ColorBytes(J + 1) = TheColor.G
ColorBytes(J + 2) = TheColor.B
J += 3
Next
For x As Int16 = (13) To (780)
out.WriteByte(pixels(x))
Next
out.Write(ColorBytes, 0, ColorBytes.Length)
out.Flush()
Dim n As Integer = (3 * 256) - colorTab.Length ;
For i As Integer = 0 To n
out.WriteByte(0)
Next
End Sub
/**
* Encodes and writes pixel data
*/
Protected Sub writePixels() throws IOException {
Dim encoder As New LZWEncoder1
encoder.LZWEncoder(width, height, indexedPixels, colorDepth)
encoder.encode(out)
For x As Long = 799 To pixels.Length - 2
If x = 796 Then
If firstFrame = True Then
pixels(x) = 0
Else
pixels(x) = &H80 Or 0 Or 0 Or 0 Or palSize
End If
End If
If x = 786 Then
writeShort(delay)
Else
out.WriteByte(pixels(x))
Console.WriteLine(x & " - " & pixels(x))
End If
Next x
out.WriteByte(8)
out.WriteByte(0)
End While
End Sub
/**
* Write 16-bit value to output stream, LSB first
*/
Protected Sub writeShort(ByVal value As Int16) throws IOException {
out.Write(System.Text.ASCIIEncoding.Unicode.GetBytes(value And &HFF), 0, Len(value))
Dim val1 As Int16, val2 As Int16
val1 = value And &HFF
val2 = (value >> 8) And &HFF
Dim bytes() As Byte = System.BitConverter.GetBytes(val1)
bytes = System.Text.Encoding.ASCII.GetBytes(value)
out.Write(bytes, 0, bytes.Length - 1)
Dim bytes2() As Byte = System.BitConverter.GetBytes(val2)
out.Write(bytes2, 0, bytes2.Length - 1)
out.WriteByte(value And &HFF)
out.WriteByte((value >> 8) And &HFF)
End Sub
/**
* Writes string to output stream
*/
Protected Sub writeString(ByVal s As String) throws IOException {
For i As Integer = 0 To s.Length() - 1
out.Write(System.Text.Encoding.ASCII.GetBytes(s), 0, System.Text.Encoding.ASCII.GetByteCount(s.Length))
out.WriteByte(AscW(s(i)))
Next
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
End Sub
End Class
Continue reading...
Public Class AnimatedGif
Protected width As Integer
Protected height As Integer
Protected transparent As Color
Protected transIndex As Integer ; // transparent index in color table
Protected repeat As Integer = -1 ; // no repeat
Protected delay As Integer = 0 ; // frame delay (hundredths)
Protected started As Boolean = False ; // ready to output frames
Protected out As IO.FileStream
Protected MyOut As IO.FileStream
Protected image1 As Image ; // current frame
Protected pixels() As Byte ; // BGR byte array from frame
Protected indexedPixels() As Byte ; // converted frame indexed to palette
Protected colorDepth As Integer ; // number of bit planes
Protected colorTab() As Byte ; // RGB palette
Protected usedEntry(256) As Boolean = new boolean[256]; // active palette entries
Protected palSize As Integer = 7 ; // color table size (bits-1)
Protected dispose As Integer = -1 ; // disposal code (-1 = use default)
Protected closeStream As Boolean = False ; // close stream when finished
Protected firstFrame As Boolean = True ;
Protected sizeSet As Boolean = False ; // if false, get size from first frame
Protected sample As Integer = 10 ; // default sample interval for quantizer
Public Sub setDelay(ByVal ms As Integer)
delay = Math.Round(ms / 10.0F)
End Sub
Public Sub setDispose(ByVal code As Integer)
If code >= 0 Then
dispose = code
End If
End Sub
Public Sub setRepeat(ByVal iter As Integer)
If iter >= 0 Then
repeat = iter
End If
End Sub
Public Sub setTransparent(ByVal c As Color)
transparent = c
End Sub
Protected Function findClosest(ByVal c As Color) As Int16
End Function
Dim colorpal As Drawing.Imaging.ColorPalette
Public Function addFrame(ByVal im As Image) As Boolean
If IsNothing(im) Or started = False Then
MsgBox("Error Loading Image", MsgBoxStyle.Critical, "Error")
Return False
End If
Dim ok As Boolean = True
Try
If sizeSet = False Then
// use first frames size
setSize(im.Width, im.Height)
image1 = im.Clone
Else
If im.Width <> width Or im.Height <> height Then
Dim G = Graphics.FromImage(image1)
G.DrawImage(im, 0, 0, image1.Width, image1.Height)
G.Dispose()
End If
End If
getImagePixels() // convert to correct format if necessary
analyzePixels() // build color table & map pixels
colorpal = image1.Palette
If firstFrame = True Then
writeLSD() // logical screen descriptior
out.Flush()
writePalette() // global color table
If (repeat >= 0) Then
// use NS app extension to indicate reps
writeNetscapeExt()
End If
Else
End If
writeres()
writeGraphicCtrlExt() ; // write graphic control extension
writeImageDesc() ; \// image descriptor
If firstFrame = False Then ) {
writePalette()
End If
writePixels() // encode and write pixel data
firstFrame = False
Catch
ok = False
End Try
Return ok
End Function
Public Function finish() As Boolean
If started = False Then Return False
Dim ok As Boolean = True
started = False
Try
out.WriteByte(&H3B) ; // gif trailer
out.Flush() ;
If (closeStream = True) Then
out.Close()
out.Dispose()
image1.Dispose()
End If
Catch
ok = False
End Try
// reset for subsequent use
transIndex = 0 ;
out = Nothing
image1 = Nothing
ReDim pixels(0)
ReDim indexedPixels(0)
ReDim colorTab(0)
closeStream = False
firstFrame = True
Return ok
End Function
/**
* Sets frame rate in frames per second. Equivalent to
*
Code:
setDelay(1000/fps)
*
* @param fps float frame rate (frames per second)
*/
Public Sub setFrameRate(ByVal fps As Single)
If fps <> 0 Then
delay = Math.Round(100.0F / fps)
End If
End Sub
/**
* Sets quality of color quantization (conversion of images
* to the maximum 256 colors allowed by the GIF specification).
* Lower values (minimum = 1) produce better colors, but slow
* processing significantly. 10 is the default, and produces
* good color mapping at reasonable speeds. Values greater
* than 20 do not yield significant improvements in speed.
*
* @param quality int greater than 0.
* @return
*/
Public Sub setQuality(ByVal quality As Integer)
If quality < 1 Then quality = 1
sample = quality
End Sub
/**
* Sets the GIF frame size. The default size is the
* size of the first frame added if this method is
* not invoked.
*
* @param w int frame width.
* @param h int frame width.
*/
Public Sub setSize(ByVal w As Integer, ByVal h As Integer)
If started = True And firstFrame = False Then Exit Sub
width = w
height = h
If (width < 1) Then width = 320
If (height < 1) Then height = 240
sizeSet = True
End Sub
/**
* Initiates GIF file creation on the given stream. The stream
* is not closed automatically.
*
* @param os OutputStream on which GIF images are written.
* @return false if initial write failed.
*/
Public Overloads Function start(ByRef os As IO.FileStream) As Boolean
If IsNothing(os) Then Return False
Dim ok As Boolean = True
closeStream = False
out = os
Try
writeString("GIF89a") ; // header
Catch
ok = False
End Try
started = ok
Return started
End Function
/**
* Initiates writing of a GIF file with the specified name.
*
* @param file String containing output file name.
* @return false if open or initial write failed.
*/
Dim outputstream As System.IO.StreamWriter
Public Overloads Function start(ByVal file As String)
Dim ok As Boolean = True
Try
outputstream = New System.IO.StreamWriter(file)
Try
out.Dispose()
Catch
End Try
out = New IO.FileStream(file, IO.FileMode.Create)
ok = start(out)
closeStream = True
Catch
ok = False
End Try
started = ok
Return started
End Function
/**
* Analyzes image colors and creates color map.
*/
/**
* Returns index of palette color closest to c
*
*/
/**
* Extracts image pixels into byte array "pixels"
*/
Protected Sub getImagePixels()
Dim w As Integer = image1.Width()
Dim h As Integer = image1.Height()
Dim thetype As Integer = image1.GetType
If w <> width Or h <> height Then
image1 = New Bitmap(width, height)
End If
if ((w != width)
|| (h != height)
|| (type != BufferedImage.TYPE_3BYTE_BGR)) {
// create new image with right size/format
dim temp as Image = new Bitmap(width,height,
new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = temp.createGraphics();
g.drawImage(image, 0, 0, null);
image = temp;
}
colorpal.
For x As Int16 = 0 To pixels.Count - 1
Console.WriteLine(x & ":" & Hex(x) & ":" & Hex(pixels(x)) & " : " & CStr(x))
Next
Try
Array.Clear(pixels, 0, pixels.Length)
Catch
End Try
ReDim pixels(0)
Dim mem As New IO.MemoryStream
image1.Save(mem, System.Drawing.Imaging.ImageFormat.Gif)
pixels = mem.ToArray
colorpal = image1.Palette.Entries
End Sub
/**
* Writes Graphic Control Extension
*/
Protected Sub writeGraphicCtrlExt()
Dim transp As Integer, disp As Integer
If transparent = Nothing Then
transp = 0
disp = 0 // dispose = no action
Else
transp = 1
disp = 2 ; // force clear if using transparent color
End If
If (dispose >= 0) Then
disp = dispose & 7 ; // user override
End If
disp <<= 2
out.WriteByte(0)
out.WriteByte(&H21) ; // extension introducer
out.WriteByte(&HF9) ; // GCE label
out.WriteByte(&H4) ; // data block size
out.WriteByte(&H4)
// packed fields
out.WriteByte(0 Or 2 Or 0 Or 1) // 1:3 reserved
out.WriteByte(&H1)
disp | // 4:6 disposal
0 | // 7 user input - 0 = none
transp); // 8 transparency flag
writeShort(delay)
56) ; // delay x 1/100 sec
out.WriteByte(pixels(787)) ; // transparent color index
out.WriteByte(0) ; // block terminator
out.Flush()
End Sub
/**
* Writes Image Descriptor
*/
Protected Sub writeImageDesc()
Exit Sub
out.WriteByte(&H2C) ; // image separator
writeShort(0) ; // image position x,y = 0,0
writeShort(0) ;
writeShort(width) ; // image size
writeShort(height) ;
// packed fields
firstFrame = False
If firstFrame = True Then
// no LCT - GCT is used for first (or only) frame
out.WriteByte(0)
Else
// specify normal LCT
out.WriteByte(&H80 Or 0 Or 0 Or 0 Or palSize) // 1 local color table 1=yes
0 | // 2 interlace - 0=no
0 | // 3 sorted - 0=no
0 | // 4-5 reserved
palSize); // 6-8 size of color table
End If
End Sub
/**
* Writes Logical Screen Descriptor
*/
Protected Sub writeLSD() throws IOException {
// logical screen size
out.Flush()
writeShort(width)
writeShort(height)
// packed fields
out.WriteByte(&H80 Or &H70 Or &H0 Or palSize) | // 1 : global color table flag = 1 (gct used)
0x70 | // 2-4 : color resolution = 7
0x00 | // 5 : gct sort flag = 0
palSize)); // 6-8 : gct size
out.WriteByte(0) ; // background color index
out.WriteByte(0) ; // pixel aspect ratio - assume 1:1
out.Write(pixels, 0, 12)
End Sub
/**
* Writes Netscape application extension to define
* repeat count.
*/
Dim NetOffSet As Integer = 0
Protected Sub writeNetscapeExt() throws IOException {
out.WriteByte(&H21) ; // extension introducer
out.WriteByte(&HFF) ; // app extension label
out.WriteByte(11) ; // block size
writeString("NETSCAPE" & "2.0") ; // app id + auth code
out.WriteByte(3) ; // sub-block size
out.WriteByte(1) ; // loop sub-block id
writeShort(repeat) ; // loop count (extra iterations, 0=repeat forever)
out.WriteByte(0) ; // block terminator
NetOffSet = 19
End Sub
/**
* Writes color table
Dim ColorBytes(767) As Byte
Protected Sub writePalette() throws IOException {
out.Write(colorTab, 0, colorTab.Length - 1) , 0, colorTab.Length)
Dim J As Integer = 0
For a As Int16 = 0 To colorpal.Entries.Length - 1
TheColor = colorpal.Entries(a)
ColorBytes(J) = TheColor.R
ColorBytes(J + 1) = TheColor.G
ColorBytes(J + 2) = TheColor.B
J += 3
Next
For x As Int16 = (13) To (780)
out.WriteByte(pixels(x))
Next
out.Write(ColorBytes, 0, ColorBytes.Length)
out.Flush()
Dim n As Integer = (3 * 256) - colorTab.Length ;
For i As Integer = 0 To n
out.WriteByte(0)
Next
End Sub
/**
* Encodes and writes pixel data
*/
Protected Sub writePixels() throws IOException {
Dim encoder As New LZWEncoder1
encoder.LZWEncoder(width, height, indexedPixels, colorDepth)
encoder.encode(out)
For x As Long = 799 To pixels.Length - 2
If x = 796 Then
If firstFrame = True Then
pixels(x) = 0
Else
pixels(x) = &H80 Or 0 Or 0 Or 0 Or palSize
End If
End If
If x = 786 Then
writeShort(delay)
Else
out.WriteByte(pixels(x))
Console.WriteLine(x & " - " & pixels(x))
End If
Next x
out.WriteByte(8)
out.WriteByte(0)
End While
End Sub
/**
* Write 16-bit value to output stream, LSB first
*/
Protected Sub writeShort(ByVal value As Int16) throws IOException {
out.Write(System.Text.ASCIIEncoding.Unicode.GetBytes(value And &HFF), 0, Len(value))
Dim val1 As Int16, val2 As Int16
val1 = value And &HFF
val2 = (value >> 8) And &HFF
Dim bytes() As Byte = System.BitConverter.GetBytes(val1)
bytes = System.Text.Encoding.ASCII.GetBytes(value)
out.Write(bytes, 0, bytes.Length - 1)
Dim bytes2() As Byte = System.BitConverter.GetBytes(val2)
out.Write(bytes2, 0, bytes2.Length - 1)
out.WriteByte(value And &HFF)
out.WriteByte((value >> 8) And &HFF)
End Sub
/**
* Writes string to output stream
*/
Protected Sub writeString(ByVal s As String) throws IOException {
For i As Integer = 0 To s.Length() - 1
out.Write(System.Text.Encoding.ASCII.GetBytes(s), 0, System.Text.Encoding.ASCII.GetByteCount(s.Length))
out.WriteByte(AscW(s(i)))
Next
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
End Sub
End Class
Continue reading...