玩坏的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