玩坏的BadApple终于有了第三弹~
这一次,我们将使用VisualBasic来玩坏BadApple
整的程序包括图片播放器(ConsolePlayer)和图片解析器(PictureReader)
图片播放器:
MainModule.vb文件源代码:
Imports System.Text
Module MainModule
Private strPath As String
Private strWhite As String
Private intSleep As Integer
Private intMaxNumber As Integer
Sub Main()
strPath = Replace(Console.Title, "file:///", String.Empty) '本行代码是为了解决VS环境中调试时标题不同而设计的,离开VS运行时不需要
strPath = Replace(strPath.ToLower(), ".exe", ".txt")
Console.WriteLine("=====================================================================" & vbCrLf & vbCrLf)
Console.WriteLine("文件:" & vbCrLf & strPath & vbCrLf & vbCrLf & "请输入总帧数:")
intMaxNumber = CInt(Console.ReadLine())
Console.WriteLine(vbCrLf & "请输入延时(毫秒):")
intSleep = CInt(Console.ReadLine()) '延时试帧率而定
Console.WriteLine(vbCrLf & "请输入表示白色的字符(仅1个半角英文字符):")
strWhite = Console.ReadLine(0)
strWhite = strWhite & strWhite
Console.WriteLine(vbCrLf & "按任意键开始...")
Console.ReadKey()
Dim a As New Stopwatch
a.Start()
Try
Dim sb As New StringBuilder()
Dim objFile As New System.IO.StreamReader(strPath, System.Text.Encoding.Default)
Dim strLine As String
For intPictureNumber As Integer = 1 To intMaxNumber
For i As Integer = 1 To 31
strLine = Replace(objFile.ReadLine(), "1", " ")
strLine = Replace(strLine, "0", strWhite)
sb.Append(strLine)
Next i
Console.WriteLine(sb.ToString)
sb.Clear()
'Console.ReadKey() '逐帧播放
System.Threading.Thread.Sleep(intSleep) '延时试帧率而定
Console.Clear()
Next intPictureNumber
a.Stop()
Console.WriteLine("总耗时:" & a.ElapsedMilliseconds.ToString & "ms")
Console.WriteLine("平均耗时:" & CInt((a.ElapsedMilliseconds / intMaxNumber)).ToString & "ms")
objFile.Close()
objFile.Dispose()
Console.WriteLine(vbCrLf & "按任意键退出...")
Console.ReadKey()
Catch ex As Exception
End Try
End Sub
End Module
图片解析器源代码:
ImageSpliter.vb
Imports System.Drawing
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text
Public Class ImageSpliter
'小图数据
Private Structure Block
Public x, y As Integer '存所在整张图的位置
'Public Data(,) As Byte '存01
Public data As Byte
End Structure
'像素点
Private Structure Pixel
Public r, g, b As Byte
End Structure
'区块数组
Private m_blocks(,) As Block
'像素点缓存数组
Private m_pxs(,) As Pixel
Private m_bmp As Bitmap
Private m_file As String
''' <summary>
''' 高效图像RGB数据缓存
''' </summary>
''' <remarks></remarks>
Private Sub cache()
If Not File.Exists(m_file) Then
Throw New Exception("文件未找到")
Return
End If
Dim rect As New Rectangle(0, 0, m_bmp.Width, m_bmp.Height)
Dim bmd As Imaging.BitmapData = m_bmp.LockBits(rect, Imaging.ImageLockMode.ReadOnly, m_bmp.PixelFormat)
ReDim m_pxs(rect.Height - 1, rect.Width - 1)
'//逐行扫描获取颜色值
Dim px As Pixel
For row As Integer = 0 To rect.Height - 1
Dim start As Integer = row * bmd.Stride
Dim byteLen As Integer = Math.Abs(bmd.Stride)
Dim buffer(byteLen - 1) As Byte
Marshal.Copy(bmd.Scan0 + bmd.Stride * row, buffer, 0, byteLen)
Dim k As Integer = 0
For i As Integer = 0 To byteLen - 3 Step 3
px.r = buffer(i + 2)
px.g = buffer(i + 1)
px.b = buffer(i)
m_pxs(row, k) = px
k += 1
Next
Next
m_bmp.UnlockBits(bmd)
End Sub
''' <summary>
''' 全图扫描
''' </summary>
''' <param name="n">横向</param>
''' <param name="m">纵向</param>
''' <remarks></remarks>
Public Sub scan(ByVal n As Integer, ByVal m As Integer)
If m_bmp Is Nothing Then
Throw New Exception("未初始化图像")
Exit Sub
End If
If n <= 0 Or m <= 0 Then
Throw New Exception("参数无效")
Exit Sub
End If
Dim bounds As RectangleF = m_bmp.GetBounds(GraphicsUnit.Pixel)
'为所有区块分配空间
ReDim m_blocks(m - 1, n - 1)
Dim pw As Integer = CInt(bounds.Width / n)
Dim ph As Integer = CInt(bounds.Height / m)
For i As Integer = 0 To m - 1
For j As Integer = 0 To n - 1
m_blocks(i, j) = New Block
'为每个区块分配空间
'ReDim m_blocks(i, j).Data(pw - 1, ph - 1)
m_blocks(i, j).x = i + 1
m_blocks(i, j).y = j + 1
'x,y为全图坐标指向;a,b为data数组索引
Dim a, b, x, y As Integer
a = 0
b = 0
Dim sumBlack As Double = 0
Dim sum As Double = 0
'//遍历区块
For x = i * pw To (i + 1) * pw - 1
For y = j * ph To (j + 1) * ph - 1
If y >= m_bmp.Width Or x >= m_bmp.Height Then Exit For
Dim pxColor As Pixel = m_pxs(x, y)
If (pxColor.r < 240 And pxColor.g < 240 And pxColor.b < 240) Then
'//m_blocks(i, j).Data(a, b) = 1
sumBlack += 1
'//Else
'//m_blocks(i, j).Data(a, b) = 0
End If
sum += 1
b += 1
Next
a += 1
b = 0
Next
'//
If sumBlack / sum > 0.5F Then
m_blocks(i, j).data = 1
Else
m_blocks(i, j).data = 0
End If
Next
Next
End Sub
''' <summary>
''' 整理成字符串返回
''' </summary>
''' <returns>返回StringBuilder类</returns>
''' <remarks></remarks>
Public Function dumpTo() As StringBuilder
Dim sb As New StringBuilder()
sb.Capacity = m_blocks.GetUpperBound(0) * m_blocks.GetUpperBound(1)
For i As Integer = 0 To m_blocks.GetUpperBound(0)
For j As Integer = 0 To m_blocks.GetUpperBound(1)
sb.Append(m_blocks(i, j).data)
Next
sb.AppendLine()
Next
'For Each blc As Block In m_blocks
'For i As Integer = 0 To blc.Data.GetUpperBound(1)
'For j As Integer = 0 To blc.Data.GetUpperBound(0)
'sb.Append(blc.data)
'Next j
'sb.AppendLine()
'Next i
'sb.AppendLine()
'Next
Return sb
End Function
''' <summary>
''' 构造函数
''' </summary>
''' <param name="file"></param>
''' <remarks></remarks>
Public Sub New(ByRef file As String)
setFile(file)
End Sub
Public Sub New()
End Sub
''' <summary>
''' 改变文件
''' </summary>
''' <param name="filename"></param>
''' <remarks></remarks>
Public Sub setFile(ByRef filename As String)
m_file = filename
If m_bmp IsNot Nothing Then
m_bmp.Dispose()
End If
m_bmp = New Bitmap(filename)
Call cache()
End Sub
End Class
MainForm.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class MainForm
Inherits System.Windows.Forms.Form
'Form 重写 Dispose,以清理组件列表。
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Windows 窗体设计器所必需的
Private components As System.ComponentModel.IContainer
'注意: 以下过程是 Windows 窗体设计器所必需的
'可以使用 Windows 窗体设计器修改它。
'不要使用代码编辑器修改它。
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.pgbProgress = New System.Windows.Forms.ProgressBar()
Me.lblProgress = New System.Windows.Forms.Label()
Me.btnCancel = New System.Windows.Forms.Button()
Me.txtFolder = New System.Windows.Forms.TextBox()
Me.lblFolder = New System.Windows.Forms.Label()
Me.btnFolder = New System.Windows.Forms.Button()
Me.lblFileName = New System.Windows.Forms.Label()
Me.txtFileName = New System.Windows.Forms.TextBox()
Me.lblInfo = New System.Windows.Forms.Label()
Me.lblMinNumber = New System.Windows.Forms.Label()
Me.nupMinNumber = New System.Windows.Forms.NumericUpDown()
Me.lblMaxNumber = New System.Windows.Forms.Label()
Me.nupMaxNumber = New System.Windows.Forms.NumericUpDown()
Me.ptbPicture1st = New System.Windows.Forms.PictureBox()
Me.ptbPicture2nd = New System.Windows.Forms.PictureBox()
Me.ptbPictureLast = New System.Windows.Forms.PictureBox()
Me.lblPicture1st = New System.Windows.Forms.Label()
Me.lblPicture2nd = New System.Windows.Forms.Label()
Me.lblPictureLast = New System.Windows.Forms.Label()
Me.lblName1st = New System.Windows.Forms.Label()
Me.lblName2nd = New System.Windows.Forms.Label()
Me.lblNameLast = New System.Windows.Forms.Label()
Me.lblType = New System.Windows.Forms.Label()
Me.txtType = New System.Windows.Forms.TextBox()
Me.btnStart = New System.Windows.Forms.Button()
Me.fbdFolder = New System.Windows.Forms.FolderBrowserDialog()
Me.sfdSave = New System.Windows.Forms.SaveFileDialog()
Me.btnTest = New System.Windows.Forms.Button()
Me.btnBigGift = New System.Windows.Forms.Button()
CType(Me.nupMinNumber, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.nupMaxNumber, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.ptbPicture1st, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.ptbPicture2nd, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.ptbPictureLast, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'pgbProgress
'
Me.pgbProgress.Location = New System.Drawing.Point(12, 317)
Me.pgbProgress.Name = "pgbProgress"
Me.pgbProgress.Size = New System.Drawing.Size(560, 23)
Me.pgbProgress.TabIndex = 0
Me.pgbProgress.Visible = False
'
'lblProgress
'
Me.lblProgress.AutoSize = True
Me.lblProgress.Location = New System.Drawing.Point(281, 343)
Me.lblProgress.Name = "lblProgress"
Me.lblProgress.Size = New System.Drawing.Size(23, 12)
Me.lblProgress.TabIndex = 1
Me.lblProgress.Text = "00%"
Me.lblProgress.Visible = False
'
'btnCancel
'
Me.btnCancel.Location = New System.Drawing.Point(255, 358)
Me.btnCancel.Name = "btnCancel"
Me.btnCancel.Size = New System.Drawing.Size(75, 23)
Me.btnCancel.TabIndex = 2
Me.btnCancel.Text = "取消(&C)"
Me.btnCancel.UseVisualStyleBackColor = True
Me.btnCancel.Visible = False
'
'txtFolder
'
Me.txtFolder.Location = New System.Drawing.Point(59, 12)
Me.txtFolder.Name = "txtFolder"
Me.txtFolder.Size = New System.Drawing.Size(432, 21)
Me.txtFolder.TabIndex = 3
'
'lblFolder
'
Me.lblFolder.AutoSize = True
Me.lblFolder.Location = New System.Drawing.Point(12, 17)
Me.lblFolder.Name = "lblFolder"
Me.lblFolder.Size = New System.Drawing.Size(41, 12)
Me.lblFolder.TabIndex = 4
Me.lblFolder.Text = "文件夹"
'
'btnFolder
'
Me.btnFolder.Location = New System.Drawing.Point(497, 10)
Me.btnFolder.Name = "btnFolder"
Me.btnFolder.Size = New System.Drawing.Size(75, 23)
Me.btnFolder.TabIndex = 5
Me.btnFolder.Text = "浏览(&V)..."
Me.btnFolder.UseVisualStyleBackColor = True
'
'lblFileName
'
Me.lblFileName.AutoSize = True
Me.lblFileName.Location = New System.Drawing.Point(12, 42)
Me.lblFileName.Name = "lblFileName"
Me.lblFileName.Size = New System.Drawing.Size(41, 12)
Me.lblFileName.TabIndex = 6
Me.lblFileName.Text = "文件名"
'
'txtFileName
'
Me.txtFileName.Location = New System.Drawing.Point(59, 39)
Me.txtFileName.Name = "txtFileName"
Me.txtFileName.Size = New System.Drawing.Size(513, 21)
Me.txtFileName.TabIndex = 7
'
'lblInfo
'
Me.lblInfo.Location = New System.Drawing.Point(12, 63)
Me.lblInfo.Name = "lblInfo"
Me.lblInfo.Size = New System.Drawing.Size(560, 30)
Me.lblInfo.TabIndex = 8
Me.lblInfo.Text = "文件名及编号格式:文件名 + 下划线 + 六位编。以下输入最小、最大编号时不需要输入前面的0,比如编号为001190,则输入1190即可。扩展名不要加点(.)。"
'
'lblMinNumber
'
Me.lblMinNumber.AutoSize = True
Me.lblMinNumber.Location = New System.Drawing.Point(10, 98)
Me.lblMinNumber.Name = "lblMinNumber"
Me.lblMinNumber.Size = New System.Drawing.Size(53, 12)
Me.lblMinNumber.TabIndex = 9
Me.lblMinNumber.Text = "最小编号"
'
'nupMinNumber
'
Me.nupMinNumber.Location = New System.Drawing.Point(69, 96)
Me.nupMinNumber.Maximum = New Decimal(New Integer() {999999, 0, 0, 0})
Me.nupMinNumber.Name = "nupMinNumber"
Me.nupMinNumber.Size = New System.Drawing.Size(196, 21)
Me.nupMinNumber.TabIndex = 10
'
'lblMaxNumber
'
Me.lblMaxNumber.AutoSize = True
Me.lblMaxNumber.Location = New System.Drawing.Point(317, 98)
Me.lblMaxNumber.Name = "lblMaxNumber"
Me.lblMaxNumber.Size = New System.Drawing.Size(53, 12)
Me.lblMaxNumber.TabIndex = 11
Me.lblMaxNumber.Text = "最大编号"
'
'nupMaxNumber
'
Me.nupMaxNumber.Location = New System.Drawing.Point(376, 96)
Me.nupMaxNumber.Maximum = New Decimal(New Integer() {999999, 0, 0, 0})
Me.nupMaxNumber.Name = "nupMaxNumber"
Me.nupMaxNumber.Size = New System.Drawing.Size(196, 21)
Me.nupMaxNumber.TabIndex = 12
Me.nupMaxNumber.Value = New Decimal(New Integer() {200, 0, 0, 0})
'
'ptbPicture1st
'
Me.ptbPicture1st.Location = New System.Drawing.Point(13, 162)
Me.ptbPicture1st.Name = "ptbPicture1st"
Me.ptbPicture1st.Size = New System.Drawing.Size(160, 120)
Me.ptbPicture1st.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
Me.ptbPicture1st.TabIndex = 13
Me.ptbPicture1st.TabStop = False
'
'ptbPicture2nd
'
Me.ptbPicture2nd.Location = New System.Drawing.Point(211, 162)
Me.ptbPicture2nd.Name = "ptbPicture2nd"
Me.ptbPicture2nd.Size = New System.Drawing.Size(160, 120)
Me.ptbPicture2nd.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
Me.ptbPicture2nd.TabIndex = 14
Me.ptbPicture2nd.TabStop = False
'
'ptbPictureLast
'
Me.ptbPictureLast.Location = New System.Drawing.Point(413, 162)
Me.ptbPictureLast.Name = "ptbPictureLast"
Me.ptbPictureLast.Size = New System.Drawing.Size(160, 120)
Me.ptbPictureLast.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
Me.ptbPictureLast.TabIndex = 15
Me.ptbPictureLast.TabStop = False
'
'lblPicture1st
'
Me.lblPicture1st.AutoSize = True
Me.lblPicture1st.Location = New System.Drawing.Point(11, 147)
Me.lblPicture1st.Name = "lblPicture1st"
Me.lblPicture1st.Size = New System.Drawing.Size(65, 12)
Me.lblPicture1st.TabIndex = 16
Me.lblPicture1st.Text = "第一张图片"
'
'lblPicture2nd
'
Me.lblPicture2nd.AutoSize = True
Me.lblPicture2nd.Location = New System.Drawing.Point(209, 147)
Me.lblPicture2nd.Name = "lblPicture2nd"
Me.lblPicture2nd.Size = New System.Drawing.Size(65, 12)
Me.lblPicture2nd.TabIndex = 17
Me.lblPicture2nd.Text = "第二张图片"
'
'lblPictureLast
'
Me.lblPictureLast.AutoSize = True
Me.lblPictureLast.Location = New System.Drawing.Point(411, 147)
Me.lblPictureLast.Name = "lblPictureLast"
Me.lblPictureLast.Size = New System.Drawing.Size(77, 12)
Me.lblPictureLast.TabIndex = 18
Me.lblPictureLast.Text = "最后一张图片"
'
'lblName1st
'
Me.lblName1st.AutoSize = True
Me.lblName1st.Location = New System.Drawing.Point(11, 285)
Me.lblName1st.Name = "lblName1st"
Me.lblName1st.Size = New System.Drawing.Size(101, 12)
Me.lblName1st.TabIndex = 19
Me.lblName1st.Text = "第一张图片文件名"
'
'lblName2nd
'
Me.lblName2nd.AutoSize = True
Me.lblName2nd.Location = New System.Drawing.Point(209, 285)
Me.lblName2nd.Name = "lblName2nd"
Me.lblName2nd.Size = New System.Drawing.Size(101, 12)
Me.lblName2nd.TabIndex = 20
Me.lblName2nd.Text = "第二张图片文件名"
'
'lblNameLast
'
Me.lblNameLast.AutoSize = True
Me.lblNameLast.Location = New System.Drawing.Point(411, 285)
Me.lblNameLast.Name = "lblNameLast"
Me.lblNameLast.Size = New System.Drawing.Size(113, 12)
Me.lblNameLast.TabIndex = 21
Me.lblNameLast.Text = "最后一张图片文件名"
'
'lblType
'
Me.lblType.AutoSize = True
Me.lblType.Location = New System.Drawing.Point(12, 126)
Me.lblType.Name = "lblType"
Me.lblType.Size = New System.Drawing.Size(41, 12)
Me.lblType.TabIndex = 22
Me.lblType.Text = "扩展名"
'
'txtType
'
Me.txtType.Location = New System.Drawing.Point(59, 123)
Me.txtType.Name = "txtType"
Me.txtType.Size = New System.Drawing.Size(513, 21)
Me.txtType.TabIndex = 23
'
'btnStart
'
Me.btnStart.Location = New System.Drawing.Point(255, 317)
Me.btnStart.Name = "btnStart"
Me.btnStart.Size = New System.Drawing.Size(75, 23)
Me.btnStart.TabIndex = 24
Me.btnStart.Text = "开始(&S)"
Me.btnStart.UseVisualStyleBackColor = True
'
'fbdFolder
'
Me.fbdFolder.Description = "请选择存放图片序列的文件夹"
'
'sfdSave
'
Me.sfdSave.DefaultExt = "txt"
Me.sfdSave.Filter = "文本文档(*.txt)|*.txt"
Me.sfdSave.Title = "请选择保存解析结果的路径"
'
'btnTest
'
Me.btnTest.Location = New System.Drawing.Point(488, 358)
Me.btnTest.Name = "btnTest"
Me.btnTest.Size = New System.Drawing.Size(85, 23)
Me.btnTest.TabIndex = 25
Me.btnTest.Text = "模拟测试(&T)"
Me.btnTest.UseVisualStyleBackColor = True
'
'btnBigGift
'
Me.btnBigGift.Location = New System.Drawing.Point(12, 352)
Me.btnBigGift.Name = "btnBigGift"
Me.btnBigGift.Size = New System.Drawing.Size(100, 23)
Me.btnBigGift.TabIndex = 26
Me.btnBigGift.Text = "点我有惊喜!"
Me.btnBigGift.UseVisualStyleBackColor = True
'
'MainForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(584, 387)
Me.Controls.Add(Me.btnBigGift)
Me.Controls.Add(Me.btnTest)
Me.Controls.Add(Me.btnStart)
Me.Controls.Add(Me.txtType)
Me.Controls.Add(Me.lblType)
Me.Controls.Add(Me.lblNameLast)
Me.Controls.Add(Me.lblName2nd)
Me.Controls.Add(Me.lblName1st)
Me.Controls.Add(Me.lblPictureLast)
Me.Controls.Add(Me.lblPicture2nd)
Me.Controls.Add(Me.lblPicture1st)
Me.Controls.Add(Me.ptbPictureLast)
Me.Controls.Add(Me.ptbPicture2nd)
Me.Controls.Add(Me.ptbPicture1st)
Me.Controls.Add(Me.nupMaxNumber)
Me.Controls.Add(Me.lblMaxNumber)
Me.Controls.Add(Me.nupMinNumber)
Me.Controls.Add(Me.lblMinNumber)
Me.Controls.Add(Me.lblInfo)
Me.Controls.Add(Me.txtFileName)
Me.Controls.Add(Me.lblFileName)
Me.Controls.Add(Me.btnFolder)
Me.Controls.Add(Me.lblFolder)
Me.Controls.Add(Me.txtFolder)
Me.Controls.Add(Me.btnCancel)
Me.Controls.Add(Me.lblProgress)
Me.Controls.Add(Me.pgbProgress)
Me.MaximizeBox = False
Me.Name = "MainForm"
Me.Text = "图片解析"
CType(Me.nupMinNumber, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.nupMaxNumber, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.ptbPicture1st, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.ptbPicture2nd, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.ptbPictureLast, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents pgbProgress As System.Windows.Forms.ProgressBar
Friend WithEvents lblProgress As System.Windows.Forms.Label
Friend WithEvents btnCancel As System.Windows.Forms.Button
Friend WithEvents txtFolder As System.Windows.Forms.TextBox
Friend WithEvents lblFolder As System.Windows.Forms.Label
Friend WithEvents btnFolder As System.Windows.Forms.Button
Friend WithEvents lblFileName As System.Windows.Forms.Label
Friend WithEvents txtFileName As System.Windows.Forms.TextBox
Friend WithEvents lblInfo As System.Windows.Forms.Label
Friend WithEvents lblMinNumber As System.Windows.Forms.Label
Friend WithEvents nupMinNumber As System.Windows.Forms.NumericUpDown
Friend WithEvents lblMaxNumber As System.Windows.Forms.Label
Friend WithEvents nupMaxNumber As System.Windows.Forms.NumericUpDown
Friend WithEvents ptbPicture1st As System.Windows.Forms.PictureBox
Friend WithEvents ptbPicture2nd As System.Windows.Forms.PictureBox
Friend WithEvents ptbPictureLast As System.Windows.Forms.PictureBox
Friend WithEvents lblPicture1st As System.Windows.Forms.Label
Friend WithEvents lblPicture2nd As System.Windows.Forms.Label
Friend WithEvents lblPictureLast As System.Windows.Forms.Label
Friend WithEvents lblName1st As System.Windows.Forms.Label
Friend WithEvents lblName2nd As System.Windows.Forms.Label
Friend WithEvents lblNameLast As System.Windows.Forms.Label
Friend WithEvents lblType As System.Windows.Forms.Label
Friend WithEvents txtType As System.Windows.Forms.TextBox
Friend WithEvents btnStart As System.Windows.Forms.Button
Friend WithEvents fbdFolder As System.Windows.Forms.FolderBrowserDialog
Friend WithEvents sfdSave As System.Windows.Forms.SaveFileDialog
Friend WithEvents btnTest As System.Windows.Forms.Button
Friend WithEvents btnBigGift As System.Windows.Forms.Button
End Class
MainForm.vb
Public Class MainForm
Private strSavePath As String = String.Empty
Private blnIsTesting As Boolean = False
Private intConvertProgress As Integer = 0
Private intJump As Integer = 2
Public Property ConvertProgress() As Integer
Get
Return intConvertProgress
End Get
Set(ByVal value As Integer)
If value = Nothing Then
intConvertProgress = value
pgbProgress.Value = (intConvertProgress * 100 \ ((CInt(nupMaxNumber.Value) - CInt(nupMinNumber.Value) + 1)))
lblProgress.Text = pgbProgress.Value.ToString & "%"
Me.Refresh()
End If
End Set
End Property
Private Sub RunningForm()
txtFolder.Enabled = False
txtFileName.Enabled = False
txtType.Enabled = False
btnTest.Enabled = False
btnFolder.Enabled = False
btnStart.Visible = False
nupMinNumber.Enabled = False
nupMaxNumber.Enabled = False
pgbProgress.Value = 0
pgbProgress.Visible = True
lblProgress.Text = "00%"
lblProgress.Visible = True
End Sub
Private Sub ExRunningForm()
txtFolder.Enabled = True
txtFileName.Enabled = True
txtType.Enabled = True
btnStart.Visible = True
btnTest.Enabled = True
btnFolder.Enabled = True
nupMinNumber.Enabled = True
nupMaxNumber.Enabled = True
pgbProgress.Value = 0
pgbProgress.Visible = False
lblProgress.Text = "00%"
lblProgress.Visible = False
End Sub
Private Sub btnFolder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFolder.Click
If (fbdFolder.ShowDialog = Windows.Forms.DialogResult.OK) Then
txtFolder.Text = fbdFolder.SelectedPath.ToString
Else
Exit Sub
End If
End Sub
Private Sub ConvertStop()
Call ExRunningForm()
btnCancel.Visible = False
End Sub
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Call RunningForm()
btnCancel.Visible = True
If (sfdSave.ShowDialog = Windows.Forms.DialogResult.OK) Then
intJump = CInt(InputBox("请输入间隔帧数,1表示连续解析图片,2表示间隔1张图片解析,3表示间隔2张图片解析,以此类推。" & vbCrLf & "此功能用于减少帧数。", "请输入步长:", "2"))
strSavePath = sfdSave.FileName
Dim stw As New Stopwatch
stw.Start()
Dim sp As New ImageSpliter()
Dim intPictureNumber As Integer
Dim strFileMainName As String = txtFolder.Text & "\" & txtFileName.Text & "_"
Try
Using sr As New IO.StreamWriter(strSavePath, False, System.Text.Encoding.UTF8)
Dim sb As System.Text.StringBuilder
'Dim buf() As Char
For intPictureNumber = CInt(nupMinNumber.Value) To CInt(nupMaxNumber.Value) Step intJump
sp.setFile(strFileMainName & Format(intPictureNumber, "000000") & "." & txtType.Text)
sp.scan(40, 30)
'//buffer
sb = sp.dumpTo()
'If buf Is Nothing Then
'' ReDim buf(sb.Length - 1)
'End If
'sb.CopyTo(0, buf, 0, sb.Length)
'//写入序号
'//sr.WriteLine(intPictureNumber)
'//写入数据
'//sr.Write(buf)
sr.Write(sb.ToString())
'//换行
sr.WriteLine()
'进度条功能
'ConvertProgress = intPictureNumber - CInt(nupMinNumber.Value) + 1
Next
sr.Close()
End Using
Catch ex As Exception
MessageBox.Show("意外错误,进程终止!出错图片编号:" & intPictureNumber.ToString, "错误:", MessageBoxButtons.OK, MessageBoxIcon.Error)
Call ConvertStop()
Me.ConvertProgress = 0
nupMinNumber.Value = intPictureNumber
Exit Sub
End Try
stw.Stop()
Call ConvertStop()
MessageBox.Show("耗时:" & stw.ElapsedMilliseconds.ToString & "毫秒", "完成!", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
Call ConvertStop()
End If
End Sub
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Call ConvertStop()
End Sub
Private Sub txtFolder_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFolder.TextChanged
If ((txtFileName.Text = String.Empty) Or (txtType.Text = String.Empty) Or (txtFolder.Text = String.Empty)) Then
Exit Sub
End If
Try
If (IO.File.Exists(txtFolder.Text & "\" & txtFileName.Text & "_" & Format(nupMinNumber.Value, "000000").ToString & "." & txtType.Text)) Then
ptbPicture1st.Image = Image.FromFile(txtFolder.Text & "\" & txtFileName.Text & "_" & Format(nupMinNumber.Value, "000000").ToString & "." & txtType.Text)
lblName1st.Text = txtFileName.Text & "_" & Format(nupMinNumber.Value, "000000").ToString & "." & txtType.Text
Else
lblName1st.Text = "文件不存在"
ptbPicture1st.Image = Nothing
End If
If Not blnIsTesting Then
If (nupMinNumber.Value = nupMaxNumber.Value) Then
lblName2nd.Text = "没有第二张图片"
ptbPicture2nd.Image = Nothing
lblNameLast.Text = "没有最后一张图片"
ptbPictureLast.Image = Nothing
ElseIf (nupMinNumber.Value > nupMaxNumber.Value) Then
lblName2nd.Text = "没有第二张图片"
ptbPicture2nd.Image = Nothing
lblNameLast.Text = "没有最后一张图片"
ptbPictureLast.Image = Nothing
Else
If (IO.File.Exists(txtFolder.Text & "\" & txtFileName.Text & "_" & Format(nupMinNumber.Value + 1, "000000").ToString & "." & txtType.Text)) Then
ptbPicture2nd.Image = Image.FromFile(txtFolder.Text & "\" & txtFileName.Text & "_" & Format(nupMinNumber.Value + 1, "000000").ToString & "." & txtType.Text)
lblName2nd.Text = txtFileName.Text & "_" & Format(nupMinNumber.Value + 1, "000000").ToString & "." & txtType.Text
Else
lblName2nd.Text = "文件不存在"
ptbPicture2nd.Image = Nothing
End If
If (IO.File.Exists(txtFolder.Text & "\" & txtFileName.Text & "_" & Format(nupMaxNumber.Value, "000000").ToString & "." & txtType.Text)) Then
ptbPictureLast.Image = Image.FromFile(txtFolder.Text & "\" & txtFileName.Text & "_" & Format(nupMaxNumber.Value, "000000").ToString & "." & txtType.Text)
lblNameLast.Text = txtFileName.Text & "_" & Format(nupMaxNumber.Value, "000000").ToString & "." & txtType.Text
Else
lblNameLast.Text = "文件不存在"
ptbPictureLast.Image = Nothing
End If
End If
End If
Catch ex As Exception
End Try
End Sub
Private Sub txtFileName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFileName.TextChanged
Call txtFolder_TextChanged(sender, e)
End Sub
Private Sub nupMinNumber_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles nupMinNumber.ValueChanged
Call txtFolder_TextChanged(sender, e)
End Sub
Private Sub nupMaxNumber_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles nupMaxNumber.ValueChanged
Call txtFolder_TextChanged(sender, e)
End Sub
Private Sub txtType_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtType.TextChanged
Call txtFolder_TextChanged(sender, e)
End Sub
Private Sub MainForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
ptbPicture1st.Dispose()
ptbPicture2nd.Dispose()
ptbPictureLast.Dispose()
fbdFolder.Dispose()
sfdSave.Dispose()
End Sub
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
If (MessageBox.Show("这是一个不成熟的测试性功能,可能导致程序无响应,甚至电脑死机。您确定要使用?", "警告:", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Cancel) Then
Exit Sub
End If
If Not (IO.File.Exists(txtFolder.Text & "\" & txtFileName.Text & "_" & Format(nupMinNumber.Value, "000000").ToString & "." & txtType.Text)) Then
MessageBox.Show("测试失败", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End If
If (nupMinNumber.Value = nupMaxNumber.Value) Then
MessageBox.Show("测试失败", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
ElseIf (nupMinNumber.Value > nupMaxNumber.Value) Then
MessageBox.Show("测试失败", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End If
Dim intMinNumber As Integer = CInt(nupMinNumber.Value)
blnIsTesting = True
Try
Dim i As Integer = CInt(InputBox("每步帧数:", "请输入步进步长", "1"))
Call RunningForm()
Do Until (nupMinNumber.Value >= nupMaxNumber.Value)
nupMinNumber.Value = nupMinNumber.Value + i
pgbProgress.Value = CInt((CInt(nupMinNumber.Value) - intMinNumber + 1) * 100 / ((CInt(nupMaxNumber.Value) - intMinNumber + 1)))
lblProgress.Text = pgbProgress.Value.ToString & "%"
Me.Refresh()
Loop
Catch ex As Exception
MessageBox.Show("测试失败:意外错误。", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error)
Call ExRunningForm()
Exit Sub
End Try
Call ExRunningForm()
MessageBox.Show("测试完成")
nupMinNumber.Value = intMinNumber
blnIsTesting = False
End Sub
Private Sub MainForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If (MessageBox.Show("==========================================" & vbCrLf & _
"请您遵守相关使用协议,谢谢合作。", "关于本程序:", MessageBoxButtons.OKCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Cancel) Then
ptbPicture1st.Dispose()
ptbPicture2nd.Dispose()
ptbPictureLast.Dispose()
fbdFolder.Dispose()
sfdSave.Dispose()
Me.Dispose()
End If
End Sub
Private Sub btnBigGift_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBigGift.Click
Dim i As Integer
For i = 1 To 500
MessageBox.Show("没事别乱点!", "警告:", MessageBoxButtons.OK, MessageBoxIcon.Error)
Next i
End Sub
'Public Sub New()
'
' ' 此调用是设计器所必需的。
' InitializeComponent()
'
' ' 在 InitializeComponent() 调用之后添加任何初始化。
' Return
'
' Dim files() As String = System.IO.Directory.GetFiles("F:\imgs")
'
' For i As Integer = 0 To files.Length - 1
' Dim fname As String = String.Format("img_{0:D6}.jpeg", i)
' If Not System.IO.File.Exists("F:\imgs\" & fname) Then
' My.Computer.FileSystem.RenameFile(files(i), fname)
' End If
' Next
'
'End Sub
End Class
图片解析器使用教程:
使用本程序制作Bad Apple的过程 简要说明
第一步:对原始视频进行逐帧截图
视频必须是黑白的,4:3的长宽比(不是的请使用软件进行转换)。逐帧截图产生的图片全部放在一个文件夹中。图片的格式为JPEG,扩展名为jpeg。文件的名称要符合一下规范:
1.文件名可以自己选定,但每个图片要一样。2.编号要按照顺序连续编号,编号为6为数字,不够的在前面以0占位。3.文件名与编号间用下划线(_)分隔开。4.编号后就是点号和扩展名。
使用Sony Vegas Pro视频编辑软件渲染成JPEG图像序列即可直接获得这种符合规范的文件名的文件。
以下是一些例子:
文件名:bad apple 1 最小编号:000000 最大编号:006567 扩展名:jpeg
bad apple 1_000000.jpeg bad apple 1_000001.jpeg bad apple 1_000002.jpeg ........... bad apple 1_006567.jpeg
文件名:bad_apple 最小编号:000017 最大编号:006584 扩展名:jpeg
bad_apple_000017.jpeg bad_apple_000001.jpeg bad_apple000002.jpeg ........... bad_apple_006584.jpeg
第二步:使用PictureReader.exe对图片进行解析
按照界面上的指导填写,然后点击开始,选择保存txt文件的目录,然后输入你的间隔帧数。为了减少资源占用,提高执行效率,程序没有启用进度条的相关功能,请不要相信没动的进度条,耐心等待完成。预计速度每秒1张图(1440*1080分辨率)。由于时间较长,可能会出现程序无响应的情况,请打开你保存txt文件的目录,刷新,看看文件大小是否在增加,若在增加,则程序还在正常运行。
重要说明1:如果您真的发现程序停止响应,没有正常运行:建议您使用Windows自带的任务管理器结束进程,不要使用第三方(譬如杀毒软件)提供的任务管理器。之后,保存您正在做的工作,重启计算机。
重要说明2:点击开始后,提示输入间隔帧数时,请正确输入。这个涉及到您的Bad Apple播放减少帧率的问题。输入1表示连续解析图片,帧率不减少;2表示间隔1张图片解析,帧率减少到原来的二分之一;3表示间隔2张图片解析,帧率减少到原来的三分之一;以此类推,不支持小数、0或负数。
第三步:使用ConsolePlayer.exe播放
复制ConsolePlayer.exe到您上一步中保存txt文本文件的文件夹中,并将两个文件的文件名(不包括扩展名)改成相同的。然后执行ConsolePlayer.exe程序。输入你总计帧数【计算公式:(图片最大编号-最小编号+1)除以间隔帧数】和延时【毫秒为单位,大概值计算公式:原视频播放时间(秒)*1000除以总计帧数,具体值自行调整,仅支持正整数】,以及代表字符。
重要说明:如果您发现程序停止响应,没有正常运行:仍然建议您使用Windows自带的任务管理器结束进程,不要使用第三方(譬如杀毒软件)提供的任务管理器。之后,保存您正在做的工作,重启计算机。
图片播放器使用:
使用本程序制作Bad Apple的过程 简要说明
总帧数请输入3284
延时在50~70左右,请自行选择调整
字符通常用大写的M
任意键开始...
感谢蓝晶和Micooz提供源代码。
第四弹的BadApple,会是什么?
@ Mayuko