結合前端 jQuery Jcrop 選取區域與後端 System.Drawing (GDI+) 實際裁剪壓縮,打造完整的線上圖片編輯體驗。
<link href="Styles/jquery.Jcrop.css" rel="stylesheet" />
<script src="Scripts/jquery-1.4.1.js"></script>
<script src="Scripts/jquery.Jcrop.js"></script>
<asp:Image ID="target" runat="server" />
<div id="preImg" style="width:150px;height:80px;overflow:hidden;">
<asp:Image ID="preview" runat="server" />
</div>
<asp:HiddenField ID="x1" runat="server" />
<asp:HiddenField ID="y1" runat="server" />
<asp:HiddenField ID="Iwidth" runat="server" />
<asp:HiddenField ID="Iheight" runat="server" />
<asp:Button ID="SaveImg" runat="server" Text="裁剪並儲存" OnClick="saveImg" />
var jcrop_api, boundx, boundy;
$('#target').Jcrop({
onChange: updatePreview,
onSelect: updatePreview,
aspectRatio: 150 / 80,
minSize: [20, 20]
}, function() {
var bounds = this.getBounds();
boundx = bounds[0]; boundy = bounds[1];
jcrop_api = this;
});
function updatePreview(c) {
if (parseInt(c.w) > 0) {
var rx = 150 / c.w, ry = 80 / c.h;
$('#preview').css({
width: Math.round(rx * boundx) + 'px',
height: Math.round(ry * boundy) + 'px',
marginLeft: '-' + Math.round(rx * c.x) + 'px',
marginTop: '-' + Math.round(ry * c.y) + 'px'
});
}
$('#x1').val(c.x); $('#y1').val(c.y);
$('#Iwidth').val(c.w); $('#Iheight').val(c.h);
}
protected void saveImg(object sender, EventArgs e) {
string path = Path.Combine(UploadPath, _url);
int x = int.Parse(x1.Value), y = int.Parse(y1.Value);
int w = int.Parse(Iwidth.Value), h = int.Parse(Iheight.Value);
ImgReduceCutOut(x, y, w, h, path, path); // 覆蓋原圖
}
private void ImgReduceCutOut(int startX, int startY, int w, int h, string inUrl, string outUrl) {
using (var oldImg = Image.FromFile(inUrl)) {
oldImg.Save(Server.MapPath("temp.jpg")); // 複本操作避免鎖定
oldImg.Dispose();
}
using (var bm = new Bitmap(Server.MapPath("temp.jpg"))) {
var ici = GetEncoder(ImageFormat.Jpeg);
var ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(Encoder.Quality, 85L);
var rect = new Rectangle(startX, startY, w, h);
using (var clone = bm.Clone(rect, bm.PixelFormat)) {
if (w > StandardWidth) {
using (var thumb = clone.GetThumbnailImage(StandardWidth, StandardHeight, () => false, IntPtr.Zero)) {
thumb.Save(outUrl, ici, ep);
}
} else {
clone.Save(outUrl, ici, ep);
}
}
}
}
private ImageCodecInfo GetEncoder(ImageFormat fmt) {
return ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == fmt.Guid);
}
overflow:hidden 容器配合 margin 負值實現即時預覽。Save 臨時副本,避免原檔被鎖定導致後續讀取失敗。Encoder.Quality 控制 JPEG 輸出品質。IDisposable 物件嚴格用 using 釋放。Jcrop 官網: deepliquid.com