首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JCrop 與 ajaxUpload 實現圖片裁切上傳完整教程

     編輯:Java 綜合教學

前言

在 Web 開發中,用戶頭像上傳與裁切是常見需求。本文將詳細介紹如何結合 JCrop(jQuery 圖片裁切插件)與 ajaxUpload(非同步文件上傳)實現圖片的選取、預覽、裁切與上傳全流程。文章包含前端頁面代碼、後端處理邏輯及圖片裁切工具類,幫助開發者快速落地該功能。

功能效果展示

實現效果如下圖所示,用戶可上傳圖片、拖拽選取裁切區域、即時預覽,最後提交至後端進行裁切存儲。

JCrop 裁切上傳效果圖

所需資源下載

相關 JS、CSS 及示例圖片可從百度網盤獲取:

鏈接:https://pan.baidu.com/s/1b8SI6M 密碼:59ct

前端頁面實現

頁面基於 JSP 編寫,引入 JCrop 樣式與腳本、ajaxfileupload.js 以及 jQuery。核心結構包含目標圖片區域、預覽面板、文件選擇按鈕與提交按鈕。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
    <title>用戶頭像剪裁</title>
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
    <link rel="stylesheet" href="resources/Jcrop/css/jquery.Jcrop.css">
    <link rel="stylesheet" href="resources/css/photo.css">
    <script src="resources/js/jquery.min.js"></script>
    <script src="resources/Jcrop/js/jquery.Jcrop.js"></script>
    <script src="resources/js/ajaxfileupload.js"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="span12">
                <div class="jc-demo-box">
                    <div class="page-header">
                        <h1>頭像剪裁</h1>
                    </div>
                    <img src="resources/img/test.jpg" id="target" />
                    <div id="preview-pane">
                        <div class="preview-container">
                            <img src="resources/img/test.jpg" class="jcrop-preview"/>
                        </div>
                        <div style='float:left;display:inline;'>
                            <a class='btn_addPic' href="javascript:void(0);">
                                <span><em>+</em>添加圖片</span>
                                <input id="upload_image" type="file" name="upimage" accept="image/*" class="filePrew"/>
                            </a>
                        </div>
                        <div style='float:right;display:inline;'>
                            <a class='btn_addPic' href="javascript:void(0);" onclick='submit()'>
                                <span>提交</span>
                            </a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script type="text/javascript">
        var global_api = "";
        var boundx = "", boundy = "";
        var tag = false;

        $(function() {
            var jcrop_api;
            var $preview = $('#preview-pane');
            var $pcnt = $('#preview-pane .preview-container');
            var $pimg = $('#preview-pane .preview-container img');
            var xsize = $pcnt.width();
            var ysize = $pcnt.height();

            $('#target').Jcrop({
                onChange: updatePreview,
                onSelect: updatePreview,
                aspectRatio: xsize / ysize
            }, function() {
                var bounds = this.getBounds();
                boundx = bounds[0];
                boundy = bounds[1];
                jcrop_api = this;
                $preview.appendTo(jcrop_api.ui.holder);
            });

            function updatePreview(c) {
                if (parseInt(c.w) > 0) {
                    global_api = c;
                    var rx = xsize / c.w;
                    var ry = ysize / c.h;
                    $pimg.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'
                    });
                }
            }

            // 圖片選擇後即時預覽
            $('#upload_image').change(function(event) {
                var files = event.target.files;
                if (files && files.length > 0) {
                    var file = files[0];
                    var URL = window.URL || window.webkitURL;
                    var imgURL = URL.createObjectURL(file);
                    $('.jcrop-holder img').attr('src', imgURL);
                    $('.preview-container img').attr('src', imgURL);
                }
            });

            $("#upload_image").change(function() {
                tag = true;
            });
        });

        // 提交裁切請求
        function submit() {
            if (tag && global_api != "") {
                ajaxFileUpload();
            } else {
                alert('請先選擇圖片並進行裁切!');
            }
        }

        // 非同步文件上傳
        function ajaxFileUpload() {
            $.ajaxFileUpload({
                url: 'uploadphoto',
                secureuri: false,
                fileElementId: 'upload_image',
                dataType: 'json',
                data: {
                    x: global_api.x,
                    y: global_api.y,
                    w: global_api.w,
                    h: global_api.h,
                    pw: boundx,
                    ph: boundy,
                    unid: 'test'
                },
                success: function(data) {
                    if (data.result) {
                        alert('上傳成功');
                    } else {
                        alert('上傳失敗');
                    }
                    window.location.reload();
                }
            });
        }
    </script>
</body>
</html>

後端控制器代碼

Spring MVC 控制器接收上傳文件與裁切參數,調用工具類進行圖片裁切,並將裁切後的二進制數據存入數據庫。

@ResponseBody
@RequestMapping("uploadphoto")
public Map<String, Object> uploadPhoto(
        @RequestParam("upimage") MultipartFile imageFile,
        HttpServletRequest request,
        HttpServletResponse response) throws Exception {

    Map<String, Object> result = new HashMap<>();
    boolean success = false;

    String unid = request.getParameter("unid");
    int imageX = Integer.parseInt(request.getParameter("x"));
    int imageY = Integer.parseInt(request.getParameter("y"));
    int imageW = Integer.parseInt(request.getParameter("w"));
    int imageH = Integer.parseInt(request.getParameter("h"));
    int srcW = Integer.parseInt(request.getParameter("pw"));
    int srcH = Integer.parseInt(request.getParameter("ph"));

    try {
        if (imageFile != null && FileUploadUtil.allowUpload(imageFile.getContentType())) {
            byte[] croppedBytes = ImageCut.imgCut(
                imageFile.getInputStream(),
                imageX, imageY, imageW, imageH,
                srcW, srcH
            );

            if (croppedBytes != null) {
                User user = userService.selectByPrimaryKey(unid);
                user.setPhoto(croppedBytes);
                success = (userService.updateByPrimaryKeySelective(user) == 1);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    result.put("result", success);
    return result;
}

圖片裁切工具類

使用 Java AWT 實現圖片縮放與裁切,輸出 JPEG 格式字節數組。

package com.ssm.demo.utils;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;

public class ImageCut {

    /**
     * 裁切圖片
     * @param input 原圖輸入流
     * @param x 裁切起始 X 坐標
     * @param y 裁切起始 Y 坐標
     * @param desWidth 裁切寬度
     * @param desHeight 裁切高度
     * @param srcWidth 頁面顯示寬度
     * @param srcHeight 頁面顯示高度
     * @return 裁切後的 JPEG 字節數組
     */
    public static byte[] imgCut(InputStream input, int x, int y,
                                int desWidth, int desHeight,
                                int srcWidth, int srcHeight) {
        try {
            BufferedImage bi = ImageIO.read(input);
            if (srcWidth >= desWidth && srcHeight >= desHeight) {
                Image scaled = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
                ImageFilter cropFilter = new CropImageFilter(x, y, desWidth, desHeight);
                Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(scaled.getSource(), cropFilter));

                BufferedImage tag = new BufferedImage(desWidth, desHeight, BufferedImage.TYPE_INT_RGB);
                Graphics g = tag.getGraphics();
                g.drawImage(img, 0, 0, null);
                g.dispose();

                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageIO.write(tag, "JPEG", out);
                return out.toByteArray();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

總結

本文完整展示了 JCrop + ajaxUpload 實現圖片裁切上傳的全流程代碼。關鍵點在於:前端通過 JCrop 獲取裁切坐標與縮放比例,配合 HTML5 File API 實現本地圖片預覽;後端根據接收到的參數對原圖進行等比縮放後裁切,最終存儲為二進制數據。開發者可根據業務需求調整裁切比例、輸出格式或存儲方式(如存文件系統而非數據庫)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved