超简易图种生成器

前几天逛知乎,看到一个问题:

“有没有一段代码,让你觉得人类的智慧也可以璀璨无比?”

作为一个渣渣程序猿自然就好奇的点进去看了。
嗯。。结果就是什么都看不懂。感觉全是大牛,各种脑洞。我看了简直就是各种惊奇,心想:卧槽居然还能这样玩儿。

往下翻了好久,看到了一个比较好玩的,说让下载图片,改后缀为rar可以打开。其实这个把戏几年前就见到过了。贴吧里有时候有人发内涵图的时候就这么干过,把种子放到压缩文件,然后放进图片里。

不过那会儿完完全全的小白,啥都不懂,只是觉得挺好玩的,挺好奇怎么弄的,不过也没有去搜这个原理。(太懒了。。。)

看到这我才看了一下是怎么弄的,其实原来就只是一句cmd命令而已:
copy /b a.jpg+b.rar c.jpg

其实就是表示把一个RAR文件拼到一张图片的末尾,生成一个新的图片文件。其实不用rar也可以把其他文件压缩进图片里,只不过生成新的图片之后,改后缀名会打不开文件,提示文件已损坏。一般都是用压缩文件格式的。

回答里还看到答主还说了一句 “当年还有小伙伴写成了界面程序…找不到了。”

想想觉得这个应该挺简单的,无非就是获取一个图片路径,加上一个压缩文件的路径,然后保存生成新的图片嘛。反正当时也无聊,就做着玩一下。。

于是乎,就有了下面这个界面。。。

Alt text

WinForm在大二的时候学过一点儿,之后就再也没用过了,到现在两年多了。

想着是点这两个文本框,弹出文件选择的窗口。两个都选好后点生成,就弹出要保存文件的窗口,选择地址,输入文件名保存就完了。

说实话在学校还真没有学过这几个控件,或许是学过,不过一直没用过就给忘了吧。嘿嘿嘿…

不管了,打开工具箱一个个看,看着哪个顺眼,感觉是的就拖过来试试。然就有了这几个控件:

Alt text

分别给两个TextBox添加Click事件。让它们弹出文件选择的窗口,记得筛选一下文件类型

Alt text

我在textBox1_Click事件里写上 openFileDialog1.ShowDialog(); 后,发现弹出窗体 选择文件之后,文本框还是什么都没有,看来还得自己手动赋值了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void textBox1_Click(object sender, EventArgs e)
{
//弹出文件选择窗口
openFileDialog1.ShowDialog();
//获得文件名,包含全路径
string filePath = openFileDialog1.FileName;

if (!string.IsNullOrEmpty(filePath.Trim()))
{
//判断是否是图片文件,防止修改文件后缀名等操作
bool rs = IsImage(filePath);

if (rs)
{
//将选中文件的文件名显示到TextBox中
txtImg.Text = filePath;
}
else
{
MessageBox.Show("_(:з」∠)_这不是真的图片文件哦!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}

这里 IsImage(filePath) 是判断了一下选择的文件到底是不是图片文件。防止别人修改文件后缀名上传。主要就这一句:

1
System.Drawing.Image img = System.Drawing.Image.FromFile(path);

这会把文件试着转换成Image图片,如果这一句不报错,说明就是图片文件。



现在已经可以获得要压缩的图片 和文件地址了,下一步就是获取用户要保存的新图片的地址了。

在“生成”按钮的点击事件里面,首先得判断图片、和文件的路径是否为空,已经路径文件是否真的存在。

这些判断通过之后,就弹出文件另存为的窗口,同样的,也是用 saveFileDialog1.FileName 就能获取到用户输入文件名之后的文件全路径了。

现在好了,三个都能获取到了。可是接下来的问题来了… 要怎么用程序去调用cmd 并运行这条命令呢??这个我之前也是没有接触过的。。好吧,只好找度娘了。于是就有了下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private void RunCMD(string cmd)
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
p.StartInfo.CreateNoWindow = true;//不显示程序窗口
p.Start();//启动程序

//向cmd窗口发送输入信息
p.StandardInput.WriteLine(cmd + "&exit");

p.StandardInput.AutoFlush = true;
//p.StandardInput.WriteLine("exit");
//向标准输入写入要执行的命令。这里使用&是批处理命令的符号,表示前面一个命令不管是否执行成功都执行后面(exit)命令,如果不执行exit命令,后面调用ReadToEnd()方法会假死
//同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令,后者表示必须前一个命令执行失败才会执行后面的命令


//获取cmd窗口的输出信息
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();//等待程序执行完退出进程
p.Close();
}

万能的百度哇。。 到这应该就可以搞定了吧。

下面奉上全部代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace ImageRar
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void textBox1_Click(object sender, EventArgs e)
{
//选择图片
openFileDialog1.ShowDialog();
//获得文件名,包含全路径
string filePath = openFileDialog1.FileName;

if (!string.IsNullOrEmpty(filePath.Trim()))
{
//判断是否是图片文件,防止修改文件后缀名等操作
bool rs = IsImage(filePath);

if (rs)
{
//将选中文件的文件名显示到TextBox中
txtImg.Text = filePath;
}
else
{
MessageBox.Show("_(:з」∠)_这不是真的图片文件哦!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}

/// <summary>
/// 判断文件是否为图片
/// </summary>
/// <param name="path">文件的完整路径</param>
/// <returns>返回结果</returns>
public bool IsImage(string path)
{
try
{
System.Drawing.Image img = System.Drawing.Image.FromFile(path);
return true;
}
catch (Exception)
{
return false;
}
}

private void textBox2_Click(object sender, EventArgs e)
{
//选择压缩文件
openFileDialog2.ShowDialog();
//获得文件名,包含全路径
string filePath = openFileDialog2.FileName;
//将选中文件的文件名显示到TextBox中
txtFile.Text = filePath;

}

private void button1_Click(object sender, EventArgs e)
{
string path1 = txtImg.Text.Trim();
string path2 = txtFile.Text.Trim();

//判断是否为空
if (string.IsNullOrEmpty(path1))
{
MessageBox.Show("(,,•́ . •̀,,)请先选择一张图片", "Oops!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
else if (string.IsNullOrEmpty(path2))
{
MessageBox.Show("(,,•́ . •̀,,)请选择你要放进图片里的压缩文件", "Oops!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//判断文件是否存在
bool flag = true;
if (!File.Exists(path1))
{
flag = false;
MessageBox.Show("ヽ(o`皿′o)ノ图片路径不正确!", "Oops!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
if (!File.Exists(path2))
{
flag = false;
MessageBox.Show("ヽ(o`皿′o)ノ压缩文件路径不正确!", "Oops!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
if (flag)
{
//弹出文件保存窗口
saveFileDialog1.ShowDialog();
//获得用户新命名的图片文件全路径
string newFileName = saveFileDialog1.FileName;

// 文件压缩命令 eg: copy /b test.jpg+1.rar test2.jpg
StringBuilder cmd = new StringBuilder();
cmd.AppendFormat("copy /b {0}+{1} {2}", path1, path2, newFileName);
try
{
RunCMD(cmd.ToString());

DialogResult dr = MessageBox.Show("╭(●`∀´●)╯╰(●’◡’●)╮\r\n生成成功!点击确定查看", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
if (dr == DialogResult.OK)
{
Process open = new Process();
open.StartInfo.FileName = "explorer";
open.StartInfo.Arguments = @"/select," + newFileName;
open.Start();
}
}
catch (Exception ex)
{
MessageBox.Show("╮(๑•́ ₃•̀๑)╭压缩失败,错误原因:\r\n" + ex.Message, "Oops!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

}

private void RunCMD(string cmd)
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
p.StartInfo.CreateNoWindow = true;//不显示程序窗口
p.Start();//启动程序

//向cmd窗口发送输入信息
p.StandardInput.WriteLine(cmd + "&exit");

p.StandardInput.AutoFlush = true;
//p.StandardInput.WriteLine("exit");
//向标准输入写入要执行的命令。这里使用&是批处理命令的符号,表示前面一个命令不管是否执行成功都执行后面(exit)命令,如果不执行exit命令,后面调用ReadToEnd()方法会假死
//同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令,后者表示必须前一个命令执行失败才会执行后面的命令


//获取cmd窗口的输出信息
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();//等待程序执行完退出进程
p.Close();

//Console.WriteLine(output);
}
}
}

打包好的程序在这里,右键保存图片,改后缀为zip或者rar等压缩文件格式后就可以打开了。

效果图