我来优化一下代码吧。把内存流替换为文件流
[C#] 纯文本查看 复制代码
using System;
using System.Drawing;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Linq;
namespace file2jpg
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// 按钮1点击事件,选择文件并转换为图片
private void button1_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog1 = new OpenFileDialog())
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string inputFilePath = openFileDialog1.FileName;
ConvertFileToImage(inputFilePath);
}
}
}
// 将文件转换为图片
private void ConvertFileToImage(string inputFilePath)
{
string outputImagePath = Path.Combine(Path.GetDirectoryName(inputFilePath), "output.png");
byte[] fileBytes = File.ReadAllBytes(inputFilePath);
int totalPixels = (fileBytes.Length * 8 + 23) / 24; // 计算所需的总像素数
int width = (int)Math.Ceiling(Math.Sqrt(totalPixels)); // 计算图片宽度
int height = (int)Math.Ceiling((double)totalPixels / width); // 计算图片高度
using (Bitmap bitmap = new Bitmap(width, height))
{
int byteIndex = 0;
int bitOffset = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (byteIndex >= fileBytes.Length)
{
bitmap.SetPixel(x, y, Color.Black); // 如果文件读取完毕,设置像素为黑色
continue;
}
int r = GetNextByte(fileBytes, ref byteIndex, ref bitOffset);
int g = GetNextByte(fileBytes, ref byteIndex, ref bitOffset);
int b = GetNextByte(fileBytes, ref byteIndex, ref bitOffset);
Color color = Color.FromArgb(r, g, b);
bitmap.SetPixel(x, y, color); // 设置像素颜色
}
}
bitmap.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png); // 保存图片
}
MessageBox.Show("图片已保存为 " + outputImagePath);
}
// 获取下一个字节
private int GetNextByte(byte[] bytes, ref int byteIndex, ref int bitOffset)
{
int value = 0;
for (int i = 0; i < 8; i++)
{
if (byteIndex >= bytes.Length)
break;
int bit = (bytes[byteIndex] >> (7 - bitOffset)) & 1;
value = (value << 1) | bit;
bitOffset++;
if (bitOffset == 8)
{
bitOffset = 0;
byteIndex++;
}
}
return value;
}
// 按钮2点击事件,选择图片并恢复为文件
private void button2_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog2 = new OpenFileDialog())
{
openFileDialog2.Filter = "PNG Image|*.png";
if (openFileDialog2.ShowDialog() == DialogResult.OK)
{
string pngFilePath = openFileDialog2.FileName;
RestoreImageToFile(pngFilePath);
}
}
}
// 从图片恢复文件
private void RestoreImageToFile(string pngFilePath)
{
string outputDirectory = Path.GetDirectoryName(pngFilePath);
string outputFilePath = Path.Combine(outputDirectory, "restored_file");
using (Bitmap bitmap = new Bitmap(pngFilePath))
{
int width = bitmap.Width;
int height = bitmap.Height;
using (MemoryStream memoryStream = new MemoryStream())
{
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
Color color = bitmap.GetPixel(x, y);
memoryStream.WriteByte(color.R);
memoryStream.WriteByte(color.G);
memoryStream.WriteByte(color.B);
}
}
byte[] fileBytes = memoryStream.ToArray();
int index = Array.IndexOf(fileBytes, (byte)'5');
if (index != -1 && index <= fileBytes.Length - 4 && fileBytes[index + 1] == (byte)'2' && fileBytes[index + 2] == (byte)'P' && fileBytes[index + 3] == (byte)'J')
{
string fileNameWithExtension = System.Text.Encoding.Default.GetString(fileBytes, index, fileBytes.Length - index);
string originalFileName = fileNameWithExtension.Substring(0, fileNameWithExtension.Length - 4);
string originalExtension = Path.GetExtension(originalFileName);
originalFileName = originalFileName.Substring(0, originalFileName.Length - originalExtension.Length);
string restoredFilePath = Path.Combine(outputDirectory, originalFileName + originalExtension);
int count = 1;
while (File.Exists(restoredFilePath))
{
restoredFilePath = Path.Combine(outputDirectory, $"{originalFileName} ({count++}){originalExtension}");
}
File.WriteAllBytes(restoredFilePath, fileBytes.Take(index).ToArray());
MessageBox.Show("文件已恢复为 " + restoredFilePath);
}
else
{
File.WriteAllBytes(outputFilePath, fileBytes);
MessageBox.Show("未找到加密文件名,文件已恢复为 " + outputFilePath);
}
}
}
}
}
}
|