<%@ Page Title="Image Crop" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" %>
<%@ Register Assembly="AjaxUploader" Namespace="AjaxUploader.Controls" TagPrefix="au" %> 
<asp:Content ID="TitleContent" ContentPlaceHolderID="TitleContent" runat="server">Image Crop - AjaxUploader v5.3 Demos</asp:Content>
<asp:Content ID="HeaderContent" ContentPlaceHolderID="HeaderTitle" runat="server">Image Crop</asp:Content> 
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> 
<div class="demo-card"> <div class="demo-card-header">Client-Side Crop Before Upload</div> <div class="demo-card-body"> <p class="demo-description"> Crop an image on the client side before uploading using the HTML5 Canvas API.
 Select a crop region, preview the result, then upload only the cropped area.
 </p> <div class="demo-expect"><strong>What you should see:</strong> an interactive crop step before upload - the server receives the cropped result, not the original. Auto-upload is off so the crop happens first.</div> <au:AjaxFileUpload ID="Uploader1" runat="server"
 EnableImageCrop="true"
 AllowedExtensions=".jpg,.jpeg,.png,.webp"
 AutoUpload="false" /> <div id="cropArea" class="mt-3" style="display:none;"> <div class="row"> <div class="col-md-6"> <h6>Original</h6> <div style="position:relative;display:inline-block;"> <canvas id="sourceCanvas" role="img" aria-label="Source image crop workspace" style="max-width:100%;border:1px solid #dee2e6;border-radius:4px;"></canvas> </div> <div class="mt-2"> <div class="form-label small mb-1" id="cropRegionLabel">Crop Region (x, y, width, height)</div> <div class="d-flex gap-1" aria-labelledby="cropRegionLabel"> <input type="number" id="cropX" class="form-control form-control-sm" value="0" placeholder="X" aria-label="Crop X position"> <input type="number" id="cropY" class="form-control form-control-sm" value="0" placeholder="Y" aria-label="Crop Y position"> <input type="number" id="cropW" class="form-control form-control-sm" value="200" placeholder="W" aria-label="Crop width"> <input type="number" id="cropH" class="form-control form-control-sm" value="200" placeholder="H" aria-label="Crop height"> </div> <button type="button" class="btn btn-primary btn-sm mt-2" id="applyCropBtn">Apply Crop</button> </div> </div> <div class="col-md-6"> <h6>Cropped Preview</h6> <canvas id="cropCanvas" role="img" aria-label="Cropped image preview" style="max-width:100%;border:1px solid #dee2e6;border-radius:4px;"></canvas> <div class="mt-2"> <button type="button" class="btn btn-success btn-sm" id="btnUploadCropped" disabled>Upload Cropped Image</button> </div> </div> </div> </div> <div class="code-panel"> <pre><code>// Load image to canvas, crop, then upload as Blob
var ctx = cropCanvas.getContext('2d');
ctx.drawImage(sourceCanvas, x, y, w, h, 0, 0, w, h);
cropCanvas.toBlob(function(blob) {
 var file = new File([blob], 'cropped.jpg', { type: 'image/jpeg' });
 uploader.addFiles([file]);
 uploader.startUpload();
}, 'image/jpeg', 0.9);</code></pre> </div> </div>
</div> 
</asp:Content> 
<asp:Content ID="ScriptsContent" ContentPlaceHolderID="ScriptsContent" runat="server">
<script> var sourceCanvas = document.getElementById('sourceCanvas');
 var cropCanvas = document.getElementById('cropCanvas');
 var cropArea = document.getElementById('cropArea');
 var btnUploadCropped = document.getElementById('btnUploadCropped');
 var sourceImg = null;

 var uploader = window.AjaxUploader && typeof AjaxUploader.getInstance === 'function' ? AjaxUploader.getInstance('Uploader1') : null;
 if (uploader) {
 uploader.on('select', function(files) {
 var first = files && files[0];
 var file = first && (first.file || first);
 if (!file) return false;
 var reader = new FileReader();
 reader.onload = function(e) {
 sourceImg = new Image();
 sourceImg.onload = function() {
 if (!sourceCanvas || !cropArea) return;
 sourceCanvas.width = sourceImg.width;
 sourceCanvas.height = sourceImg.height;
 sourceCanvas.getContext('2d').drawImage(sourceImg, 0, 0);
 var cropWInput = document.getElementById('cropW');
 var cropHInput = document.getElementById('cropH');
 if (cropWInput) cropWInput.value = Math.min(200, sourceImg.width);
 if (cropHInput) cropHInput.value = Math.min(200, sourceImg.height);
 cropArea.style.display = 'block';
 };
 sourceImg.src = e.target.result;
 };
 reader.readAsDataURL(file);
 return false;
 });
 }

 function applyCrop() {
 if (!sourceImg || !cropCanvas || !btnUploadCropped) return;
 var cropXInput = document.getElementById('cropX');
 var cropYInput = document.getElementById('cropY');
 var cropWInput = document.getElementById('cropW');
 var cropHInput = document.getElementById('cropH');
 var x = parseInt(cropXInput ? cropXInput.value : '0') || 0;
 var y = parseInt(cropYInput ? cropYInput.value : '0') || 0;
 var w = parseInt(cropWInput ? cropWInput.value : '200') || 200;
 var h = parseInt(cropHInput ? cropHInput.value : '200') || 200;
 cropCanvas.width = w;
 cropCanvas.height = h;
 cropCanvas.getContext('2d').drawImage(sourceImg, x, y, w, h, 0, 0, w, h);
 btnUploadCropped.disabled = false;
 }
 var applyCropButton = document.getElementById('applyCropBtn');
 if (applyCropButton) applyCropButton.addEventListener('click', applyCrop);

 if (btnUploadCropped) btnUploadCropped.addEventListener('click', function() {
 if (!cropCanvas) return;
 cropCanvas.toBlob(function(blob) {
 var file = new File([blob], 'cropped.jpg', { type: 'image/jpeg' });
 if (uploader && typeof uploader.addFiles === 'function') {
 uploader.addFiles([file]);
 if (typeof uploader.startUpload === 'function') uploader.startUpload();
 }
 btnUploadCropped.disabled = true;
 btnUploadCropped.textContent = 'Uploading...';
 }, 'image/jpeg', 0.9);
 });
</script>
</asp:Content>
