Jos*_*h S 7 canvas ruby-on-rails amazon-s3 signaturepad rails-activestorage
如标题中所述,我正在尝试使用 Rails 的 Active Storage 从嵌套在 Rails 表单中的元素将图像上传到我的 S3 存储桶。到目前为止,我已经能够使用
<%= f.input :signature, type: file_field(:user, :signature), %>
Active Storage 上传图像。班上。User has_one_attached :signature当我使用 file_field 时,图像上传正确,因此这不是问题的一部分。
到目前为止我的simple_form有:
<div class="signature_pad text-center form-group">
<div class="signature_pad_heading">
Enter your Signature:
</div>
<div class="signature_pad_body">
<canvas id="signature_pad_input" height="145px" width="370px" style="height: 145px; width: 370px;" class="border" />
</div>
<div class="signature_pad_footer">
<button type="button" class="btn btn-default" onclick="signaturePad.clear()">Clear</button>
</div>
</div>
<%= f.input :signature, type: file_field(:user, :signature), value: "", as: :hidden %>
<%= f.submit "Save", class:'btn-primary btn-lg btn-md-wide', id: "signature_pad_save" %>
Run Code Online (Sandbox Code Playgroud)
我的 JavaScript 是:
<script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
<script>
const canvas = document.querySelector("canvas");
const signaturePad = new SignaturePad(canvas);
$('#signature_pad_save').click(function(event) {
if (signaturePad.isEmpty()){
alert('Please enter your signature.');
event.preventDefault();
} else {
$('#user_signature').val(
JSON.parse(
signaturePad.toDataURL()
);
}});
</script>
Run Code Online (Sandbox Code Playgroud)
使用 .toDataURL 我能够获取图像的 base64,我读到的所有内容似乎都表明这就是我需要通过 Active-Storage 发送到 S3 的全部内容。
最后:
"signature"=>"<ActionDispatch::Http::UploadedFile:0x007f7a02ad4ef8 @tempfile=#<Tempfile:/tmp/RackMultipart20180903-3527-kked3g.png>, @original_filename="signature1.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"user[signature]\"; filename=\"signature1.png\"\r\nContent-Type: image/png\r\n">},"
Run Code Online (Sandbox Code Playgroud)
"signature"=>"#<ActiveStorage::Attached::One:0x007f7a01c8b4f0>"}
Run Code Online (Sandbox Code Playgroud)
是的,这是可能的。
直接上传由类处理DirectUpload(或ActiveStorage.DirectUpload取决于您访问事物的方式)。通常DirectUpload需要 aFile来读取图像,但很方便,aFile是 a Blob,所以您几乎可以使用 aBlob来代替。Active Storage 仅需要其“文件”中的一些内容,并且几乎所有这些内容都存在于 中Blob,唯一缺少的是name属性,您可以自己添加。
所以现在我们需要Blob从画布中取出一个。这实际上很简单,因为画布有一个toBlob方法:
该
HTMLCanvasElement.toBlob()方法创建一个Blob代表画布中包含的图像的对象;该文件可以缓存在磁盘上或存储在内存中,具体由用户代理决定。
首先照常设置直接上传。然后为整个表单添加您自己的提交处理程序,大致如下所示:
const form = your_form_element;
const canvas = your_canvas_element;
const input = your_file_input;
canvas.toBlob(blob => {
// Fake out DirectUpload by manually adding a name.
blob.name = input.files[0].name;
const uploader = new DirectUpload(blob, input.dataset.directUploadUrl);
uploader.create((error, blob) => {
if(error) {
// Handle the error.
}
else {
// Add the <input type="hidden"> with the signature.
const hiddenField = document.createElement('input')
hiddenField.setAttribute('type', 'hidden');
hiddenField.setAttribute('value', blob.signed_id);
form.appendChild(hiddenField);
// And submit away...
form.submit();
}
});
}, 'image/jpeg', 0.95);
Run Code Online (Sandbox Code Playgroud)
假设您需要 JPEG,您可以根据需要使用其他内容类型,或者可以将其与原始内容匹配。我还遗漏了一些常用的提交处理程序样板。如果您已经设置了通常的全局直接上传处理程序,那么它们将在此处用于进度条等;如果您没有这些,那么您必须自己处理,上面链接的指南对所有这些都有指导。
我以前也曾做过类似的事情。imagemagick我通过gem将 base64 字符串转换回图像文件rmagick。
请参阅此问题的第三个答案的代码:How to save a base64 string as an image using ruby 。
然后,您必须将其添加到控制器的create和方法中,并使用此处描述的方法。update@user.signature.attach
| 归档时间: |
|
| 查看次数: |
2202 次 |
| 最近记录: |