Agregué la solución de use base64 image with Carrierwave en un esfuerzo por cargar una imagen de una clase de Java. Esto es lo que ahora mi clase FileUploader parece - y yo creo que es donde está el problema:Carga de Base64 de Android/Java a 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
El modelo de la imagen:
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
este momento cuando la llamada del anuncio se hace la ruta del archivo que se guarda en el db es nulo, pero todo lo demás se guarda. Aquí está la clase 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);
}
}
¿Alguien tiene alguna idea? Estuve atascado en esto todo el día. Creo que porque no sé mucho sobre Ruby estoy (1) malformando la solicitud; o (2) Implementé la imagen base64 con Carrierwave incorrectamente.
¡Funcionó muy bien! Gracias por esto. Terminé poniendo el procesamiento de parámetros en un 'before_filter: process_attached_file, only:: create' llamada para ayudar a mantener el método de crear más limpio, sin embargo. –
Estoy tratando de hacer lo mismo; ¿Puedes publicar tu código final de Java para tu aplicación de Android? – scientiffic
¿Te importa compartir tu implementación final para la función de carga en el lado de Android? He hecho algo similar y también estoy usando Rails, pero la carga real es increíblemente lenta, suponiendo que esto se deba a que estoy probando en webrick, pero me gustaría saber si redujo la imagen o redujo la resolución. de cualquier manera antes de subir – Riptyde4