Base64上传图像问题

问题描述 投票:0回答:1

很长的问题,很抱歉,但我想尽我所能表达,并以易于理解的方式提出。我有一个程序,允许用户使用JavaScript中的croppie.js裁剪图像,并将图像发送到运行Lisp程序的后端的Hunchentoot服务器。用户上载后,将Base64图像保存到.png文件时遇到问题。将发布请求发送到服务器后,我将以字符串的形式获取Base64映像,方法是通过创建字符串的子序列(不包含发布请求发送的标题)来从Base64请求中删除无效字符,并用“%”字符替换“ +”字符使Base64有效。接下来,我在字符串末尾删除子字符串+ 3D + 3D,因为我在Common Lisp中使用的s-base64库抱怨+ 3D + 3D是无效的填充,因此我将其替换为“ ==”有效填充。接下来,我使用s-base64库创建一个字节数组,将Base64字符串转换为字节数组,并将其存储在变量中。然后,我遍历字节数组并将每个字节写入输出文件。完成此操作后,我决定将字节数组的末尾打印到控制台,以便可以查看输出和结尾填充是否有效(看起来是有效的)。这是代码的一部分,带有使内容更清晰的注释:

(define-easy-handler (handle-image :uri "/handle-image.html") ()
    (let ((data-source (hunchentoot:raw-post-data :force-text t))) ;get Base64 string
      (let ((new-string (subseq data-source 36))) ;create a subsequence of Base64 string
         (let ((final-string (substitute #\+ #\% new-string))) ;substitute % for +
            (let ((end (search "+3D+3D" final-string))) ;find the invalid padding
                (setf final-string (concatenate 'string (subseq final-string 0 end) "==")) ;add valid padding
                (let ((byte-array (with-input-from-string (in final-string) ;create byte array (or simple-vector) out of Base64 string
                                     (decode-base64-bytes in))))
                   (with-open-file (out "path/path/path/path/profile-image.png" ;create output stream to store file
                                         :direction :output
                                         :if-exists :supersede
                                         :element-type 'unsigned-byte)
                      (dotimes (i (length byte-array)) ;write each byte from the byte array to output stream
                        (write-byte (aref byte-array i) out)))) ;close stream
                (format t "!!!!!!!!: ~a" (subseq final-string (- (length final-string) 30))))))) ;print ending to console to ensure proper padding
       "Upload Successful") ;send response to client

这是我的一些JavaScript代码:

$(document).ready(function(){

     $image_crop = $('#image_demo').croppie({
        enableExif: true,
        viewport: {
          width:200,
          height:200,
          type:'square' //circle
        },
        boundary:{
          width:300,
          height:300
        }
   });

如您所见,我首先创建了裁纸器。我允许用户裁切200 x 200的正方形,裁切空间的总大小为300 x300。这部分代码没有问题:

$('#upload_image').on('change', function(){
var reader = new FileReader();
reader.onload = function (event) {
  $image_crop.croppie('bind', {
    url: event.target.result
  }).then(function(){
    console.log('jQuery bind complete');
  });
}

上面,当他们选择文件时,将他们上传的图像绑定到裁切器(例如,如果您上传Facebook图像)。同样,没有问题:

 reader.readAsDataURL(this.files[0]);
$('#uploadImageModal').modal('show');

[上面我读了他们选择的文件,然后模态“弹出”,好像您正在裁剪Facebook或Instagram照片:

$('.crop_image').click(function(event){
       $image_crop.croppie('result', {
             type: 'canvas',
             size: 'viewport'
        }).then(function(response){
               $.ajax({
                    url:"handle-image.html",
                    type: "POST",
                    data:{"image": response},
                    success:function(data){
                            $('#uploadImageModal').modal('hide');
                            $('#uploaded_image').html(data);
                     }
              });
          })
       });

上面我上传了ajax请求,如果上传成功,他们将从服务器收到一条消息,说成功了,并且我也隐藏了图像裁剪模式。

现在的问题是图像只是空白。我知道Base64是有效的,因为我使用了Base64转换工具来查看字符串是否有效。我还回过头来就位,字节,像素和图像尺寸进行了研究,以了解计算机如何与它们交互,因此我不确定为什么我的图像只是显示空白。这是我网站上的农作物的外观:

enter image description here

绑定正在工作,然后我收到消息,上传成功。但是在写入图像并在文件系统中查看它之后,它要么是空白图像,要么有时会说不支持该图像类型。

之所以在本文中标记PHP,是因为我确信有人在PHP中通过ajax上传裁剪后的图像时也遇到了类似的问题,其中某些解决方案可能适用于这种情况,但显然需要我将解决方案翻译为lisp语法。我的假设是,当我将字符串转换为字节数组并将其写入文件时,我的代码出了点问题,但是我认为如果我忽略了某些内容,最好将代码的其他部分发布。

javascript php jquery base64 common-lisp
1个回答
0
投票

正如Brad所说,您应该首先尝试直接使用二进制上传。

此外:如果您在以base64编码的字符串中遇到%,则很可能意味着整个内容都经过了URL编码。快速的proposos搜索将do-urlencode作为解码该库的库。将%替换为+会产生有效的base64,但结果不一定表示有效的jpg。

也:使用let*而不是嵌套的let形式。也许使用write-sequence代替字节输出。

© www.soinside.com 2019 - 2024. All rights reserved.