Tôi đã thêm giải pháp từ use base64 image with Carrierwave trong nỗ lực tải lên hình ảnh từ lớp java. Điều này bây giờ là những gì lớp FileUploader của tôi trông như thế - và tôi tin là nơi mà vấn đề là:Tải lên Base64 từ Android/Java tới RoR Carrierwave
# encoding: utf-8
class FileUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
#START FROM BASE64 POST LINKED ABOVE
class FilelessIO < StringIO
attr_accessor :original_filename
attr_accessor :content_type
end
before :cache, :convert_base64
def convert_base64(file)
if file.respond_to?(:original_filename) &&
file.original_filename.match(/^base64:/)
fname = file.original_filename.gsub(/^base64:/, '')
ctype = file.content_type
decoded = Base64.decode64(file.read)
file.file.tempfile.close!
decoded = FilelessIO.new(decoded)
decoded.original_filename = fname
decoded.content_type = ctype
file.__send__ :file=, decoded
end
file
end
#END FROM POST LINKED ABOVE
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{model.user_id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fit => [200, 300]
end
version :web do
process :resize_to_fit => [1000, 1000]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
if original_filename
Time.new.to_i.to_s+"_"+original_filename
end
end
end
Mô hình ảnh:
class Picture < ActiveRecord::Base
belongs_to :user
belongs_to :folders
attr_accessible :user_id, :picture_name, :picture_description,
:folder_id, :picture_path, :file_save
mount_uploader :picture_path, FileUploader
before_save :update_pictures_attributes
def update_pictures_attributes
self.file_size = picture_path.file.size
end
end
Ngay bây giờ khi cuộc gọi bài viết được thực hiện các đường dẫn tập tin được lưu trong db là nil - nhưng mọi thứ khác được lưu. Đây là lớp java/android:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.*;
import org.apache.http.client.entity.*;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.*;
import org.apache.http.message.*;
import org.apache.commons.io.FileUtils;
import org.json.*;
import android.util.Base64;
import android.util.Log;
public class Uploader {
private String url;
private String fileName;
public Uploader(String url, String fileName){
this.url = url;
this.fileName = fileName;
}
public Boolean upload() throws JSONException, ClientProtocolException, IOException {
Boolean success = true;
JSONObject jsonObject = constructPictureJson();
DefaultHttpClient httpClient = new DefaultHttpClient();
ResponseHandler <String> responseHandler = new BasicResponseHandler();
HttpPost postMethod = new HttpPost(url);
postMethod.setEntity(new StringEntity(jsonObject.toString()));
postMethod.setHeader("Accept", "application/json");
postMethod.setHeader("Content-type", "application/json");
postMethod.setHeader("Data-type", "json");
try{
httpClient.execute(postMethod, responseHandler);
} catch (org.apache.http.client.HttpResponseException error){
Log.d("Uploader Class Error", "Error code: "+error.getStatusCode());
Log.d("Uploader Class Error", "Error message: "+error.getMessage());
success = false;
}
//Log.d("server resposne", response);
return success;
}
public JSONObject constructPictureJson() throws JSONException, IOException{
String userId = "1";
String folderId = "1";
String[] file = fileName.split("/");
JSONObject pictureData = new JSONObject();
pictureData.put("user_id", userId);
pictureData.put("folder_id", folderId);
pictureData.put("picture_name", "picture name");
pictureData.put("picture_description", "1");
pictureData.put("content_type", "jpg");
pictureData.put("original_filename", "base64:"+file[file.length-1]);
pictureData.put("filename", file[file.length-1]);
pictureData.put("picture_path", encodePicture(fileName));
return pictureData;
}
public String encodePicture(String fileName) throws IOException{
File picture = new File(fileName);
return Base64.encodeToString(FileUtils.readFileToByteArray(picture), Base64.DEFAULT);
}
}
Có ai có ý tưởng nào không? Tôi đã bị mắc kẹt trên tất cả các ngày này. Tôi nghĩ bởi vì tôi không biết nhiều về Ruby Tôi hoặc là (1) làm sai lệch yêu cầu; hoặc (2) Tôi đã triển khai image base64 với Carrierwave không chính xác.
Điều này thật tuyệt vời! Cám ơn vì cái này. Tôi đã kết thúc việc đặt các tham số xử lý vào một 'before_filter: process_attached_file, chỉ:: create' gọi để giúp giữ cho phương thức create cleaner hơn. –
Tôi đang cố gắng làm điều tương tự; bạn có thể đăng mã java cuối cùng cho ứng dụng Android của mình không? – scientiffic
Bạn có nhớ chia sẻ triển khai cuối cùng của mình cho chức năng tải lên ở phía bên android không? Tôi đã làm một điều tương tự và tôi cũng đang sử dụng Rails nhưng tải lên thực sự là cực kỳ chậm - im giả định điều này là bởi vì tôi đang thử nghiệm trên webrick, nhưng tôi muốn được tò mò để xem nếu bạn thu nhỏ hình ảnh xuống hoặc giảm độ phân giải bằng mọi cách trước khi tải lên – Riptyde4