Как сохранить изображение base64 в Blob с Carrierwave в Rails4?
Как описано в этом учебнике, я преобразую холст в DataUrl, а этот DataUrl-в Blob. Затем я делаю запрос ajax post и хотел бы сохранить изображение в базе данных с помощью Carrierwave.
Это мой код JS:
uploadButton.on('click', function(e) {
var dataURL = mycanvas.toDataURL("image/png;base64;");
// Get our file
var file= dataURLtoBlob(dataURL);
// Create new form data
var fd = new FormData();
// Append our Canvas image file to the form data
fd.append("image", file);
// And send it
$.ajax({
url: "/steps",
type: "POST",
data: fd,
processData: false,
contentType: false,
});
});
// Convert dataURL to Blob object
function dataURLtoBlob(dataURL) {
// Decode the dataURL
var binary = atob(dataURL.split(',')[1]);
// Create 8-bit unsigned array
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
// Return our Blob object
return new Blob([new Uint8Array(array)], {type: 'image/png'});
}
Когда я добавляю следующий код к своему контроллеру, то изображение сохраняется, но, конечно, не через carrierwave.
File.open("#{Rails.root}/public/uploads/somefilename.png", 'wb') do |f|
f.write(params[:image].read)
end
Обновленная Информация:
Это парамы для моего поста ajax запрос:
Parameters: {"image"=>#<ActionDispatch::Http::UploadedFile:0x007feac3e9a8a8 @tempfile=#<Tempfile:/var/folders/0k/q3kc7bpx3_51kc_5d2r1gqcc0000gn/T/RackMultipart20140211-1346-gj7kb7>, @original_filename="blob", @content_type="image/png", @headers="Content-Disposition: form-data; name="image"; filename="blob"rnContent-Type: image/pngrn">}
И это параметры для стандартной загрузки файла:
Parameters: {"utf8"=>"✓", "image"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007feac20c2e20 @tempfile=#<Tempfile:/var/folders/0k/q3kc7bpx3_51kc_5d2r1gqcc0000gn/T/RackMultipart20140211-1346-1ui8wq1>, @original_filename="burger.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name="image[image]"; filename="xy.jpg"rnContent-Type: image/jpegrn">}}
Если я сделаю Image.create(params[:image])
, у меня будет откат транзакции...
Ошибка отката транзакции:
Unprocessable Entity
ActiveRecord::RecordInvalid (Validation failed: image You are not allowed to upload "" files, allowed types: jpg, jpeg, gif, png)
2 ответа:
Вы вносите в белый список разрешенные типы файлов. По умолчанию Carrierwave попытается определить тип файла по расширению имени файла, которое не передается, так как это фактически объект Blob. Таким образом, вы получаете ошибку проверки о "типе" файла. Чтобы исправить это, просто добавьте ожидаемое расширение файла для объектов blob:
if params[:image].try(:original_filename) == 'blob' params[:image].original_filename << '.png' end Image.create!(image: params[:image])
Я просто хотел добавить, вы можете добавить тип файла в вашем представлении при добавлении вашего blob-объекта.
// Get our file var file = dataURLtoBlob(dataURL); // Create new form data var fd = new FormData(); // Append our Canvas image file to the form data fd.append("image", file, "blob.jpg");
Обратите внимание на окончание, когда мы определяем имя файла. Надеюсь, это кому-то поможет.
Источник: https://developer.mozilla.org/en-US/docs/Web/API/FormData/append