<%@ Page Language="C#" AutoEventWireup="true" CodeFile="upload.aspx.cs" Inherits="upload" %>
<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>多檔上傳縮圖</title>
<script src="js/jquery-1.6.2.min.js"></script>
<script>
function showError(inputId, msg) {
$(inputId).parent().append("<span class='text-danger'>" + msg + "</span>");
}
</script>
<style> li { list-style:none; padding-top:10px; } </style>
</head>
<body>
<form id="form1" runat="server" enctype="multipart/form-data" method="post">
<ul>
<li><input type="file" id="upload1" name="upload" /></li>
<li><input type="file" id="upload2" name="upload" /></li>
<li><input type="file" id="upload3" name="upload" /></li>
<li><input type="file" id="upload4" name="upload" /></li>
<li><input type="file" id="upload5" name="upload" /></li>
<li><input type="submit" id="btnPostFile" runat="server" onserverclick="btnPostFile_ServerClick" value="開始上傳" /></li>
</ul>
</form>
</body>
</html>
protected void btnPostFile_ServerClick(object sender, EventArgs e)
{
string saveRoot = Server.MapPath("~/uploadImg");
const int maxBytes = 5 * 1024 * 1024; // 5MB
if (!Directory.Exists(saveRoot)) Directory.CreateDirectory(saveRoot);
if (Request.Files.Count > 0)
{
for (int i = 0; i < Request.Files.Count; i++)
{
var posted = Request.Files[i];
string clientId = "#upload" + (i + 1);
string errorMsg = null;
if (string.IsNullOrEmpty(posted.FileName)) continue;
if (posted.ContentLength > maxBytes)
{
errorMsg = "檔案超過 5MB 限制";
}
else
{
string savePath = Path.Combine(saveRoot, posted.FileName);
if (File.Exists(savePath))
{
errorMsg = "檔案已存在:" + posted.FileName;
}
else if (IsValidImage(savePath))
{
posted.SaveAs(savePath);
CreateThumbnail(posted.InputStream, posted.FileName, saveRoot);
}
else
{
errorMsg = "僅允許 JPG/PNG 格式";
if (File.Exists(savePath)) File.Delete(savePath);
}
}
if (errorMsg != null)
Page.ClientScript.RegisterStartupScript(GetType(), "", $"showError('{clientId}', '{errorMsg}');", true);
}
}
}
private bool IsValidImage(string filePath)
{
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (var br = new BinaryReader(fs))
{
try
{
byte b1 = br.ReadByte();
byte b2 = br.ReadByte();
string magic = b1.ToString() + b2.ToString(); // 簡易串接
// JPEG: FF D8 (255 216) | PNG: 89 50 (137 80)
return magic == "255216" || magic == "13780";
}
catch { return false; }
}
}
改進建議:使用 Span<byte> 讀取前 8 位元組,完整比對 PNG (89 50 4E 47 0D 0A 1A 0A) 與 JPEG (FF D8 FF) 標準魔數,避免誤判。
private void CreateThumbnail(Stream inputStream, string originalFileName, string saveRoot)
{
using (var img = Image.FromStream(inputStream))
{
const int maxWidth = 100, maxHeight = 80;
int nW, nH;
if (img.Width > img.Height)
{
nW = maxWidth;
nH = (int)Math.Floor((double)img.Height * maxWidth / img.Width);
}
else
{
nH = maxHeight;
nW = (int)Math.Floor((double)img.Width * maxHeight / img.Height);
}
using (var bmp = new Bitmap(nW, nH))
using (var g = Graphics.FromImage(bmp))
{
g.Clear(Color.Transparent);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.DrawImage(img, new Rectangle(0, 0, nW, nH), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
string thumbName = Path.GetFileNameWithoutExtension(originalFileName) + "_small" + Path.GetExtension(originalFileName);
bmp.Save(Path.Combine(saveRoot, thumbName), img.RawFormat);
}
}
}
<input type="file" multiple> 單一控件支援多選。ImageSharp 取代 System.Drawing,支援 Linux 容器化、無 GDI+ 相依。