欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Grails - 图片上传、下载、等比压缩 博客分类: Grails&Groovy文件处理  

程序员文章站 2024-03-19 22:02:04
...

    Grails 图片上传

 

<g:form controller="attachments" action="upload" method="post" enctype="multipart/form-data">  
   <input type="file" name="file" />
   <input type="submit" value="上传"/>
</g:form>

  

def upload()
{
    def file = request.getFile("file")
    if (file.empty)
    {
        flash.message = message(code: '请选择要上传的文件')
        redirect(controller: "attachments", action: "create")
    }
        
    def fileType = file.getOriginalFilename().split('\\.')[-1]
    if (!(fileType in ['jpg', 'png', 'jpeg','pdf', 'doc', 'docx']))
    {
        flash.message = message(code: '文件格式不支持')
        redirect(controller: "attachments", action: "create")
    }

    def webrootDir = servletContext.getRealPath("/")
    File fileFolder = new File(webrootDir, "images/tempFile.${fileType}")
    file.transferTo(fileFolder)

    // 压缩图片
    def fileSize = request.getContentLength()
    if (fileType in ['jpg', 'png', 'jpeg'] && fileSize > 1024 * 1024)
    {
        def compressImg = fileServerService.compress(fileFolder.getAbsolutePath(), 1920, 1080)
        fileFolder = new File(compressImg)
    }
}

 

        为防止过大图片消耗内存,且方便存储,决定对过大文件(>1M)进行压缩。 等比压缩,图片大小可以自己指定。若图片大小不想改变,则可以将宽高指定成屏幕大小,如:w=1920,h=1080

 

def compress(String fileName, Integer w, Integer h)  
{      
    File file = new File(fileName)  
    Image img = ImageIO.read(file)  
    Integer width = img.getWidth(null)  
    Integer height = img.getHeight(null)  
  
    if (width / height > w / h)  
    {  
        h = (Integer) (height * w / width)  
    }  
    else  
    {  
        w = (Integer) (width * h / height)  
    }  
  
    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB)
    // Image.SCALE_AREA_AVERAGING、Image.SCALE_SMOOTH 这两种方式压缩效果较好
    image.getGraphics().drawImage(img.getScaledInstance(w, h, Image.SCALE_SMOOTH),0, 0, null)  
  
    File destFile = new File(fileName)  
    FileOutputStream out = new FileOutputStream(destFile)  
  
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out)  
    encoder.encode(image)  
  
    return fileName  
}

  

         目前为止,文件已经存储到项目的/images文件夹下,若想将文件统一管理,可以生产一个文件管理服务,通过接口调用,需要将图片转成Base64码传输。

 

def upload()
{
    // 接上面的upload

    // 将临时文件存储转成 Base64
    FileInputStream inputStream = new FileInputStream(fileFolder)
    ByteArrayOutputStream output = new ByteArrayOutputStream()
    byte[] fileBytes = new byte[inputStream.available()]
    Integer length = 0
    while ((length = inputStream.read(fileBytes)) != -1)
    {
        output.write(fileBytes, 0, length)
    }
    def encoded = fileBytes.encodeBase64().toString()

    // 调用接口,返回文件名(包括路径+名称)
    def fileName = fileServerService.uploadServer(encoded, fileType)
}

 

        文件服务器接收到Base64码,进行解码形成图片后存储。

 

def uploadServer()
{
    def encoded = params["encoded"]
    def fileType = params["fileType"]

    def externalId = UUID.randomUUID().toString()
    def fileName = "images/${externalId}.${fileType}"

    def webrootDir = servletContext.getRealPath("/")    
    BASE64Decoder decoder = new BASE64Decoder()
    byte[] image = decoder.decodeBuffer(encoded)
    File fileImage = new File(webrootDir, fileName)
    fileImage.append(image)

    render externalId as JSON
}

def removeServer()
{
    def externalId = params["externalId"]
    def fileType = params["fileType"]
    
    def webrootDir = servletContext.getRealPath("/")
    def fileName = "images/${externalId}.${fileType}"
    File file = new File(webrootDir, fileName)
    if (file.isFile() && file.exists())
    {
        file.delete()
        render status: 200
    }
}