2012-03-24 15 views
7

से बेस 64 अपलोड मैंने जावा क्लास से एक छवि अपलोड करने के प्रयास में use base64 image with Carrierwave से समाधान जोड़ा। यह मेरा FileUploader वर्ग कैसा दिखता है - और मैं होने के लिए जहां समस्या है विश्वास करते हैं:एंड्रॉइड/जावा से आरओआर कैरियरवेव

# 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 

चित्र मॉडल:

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 

अभी जब पोस्ट कॉल फ़ाइल पथ बना है डीबी में सहेजा गया है शून्य है - लेकिन बाकी सब कुछ बचाया गया है। यहां जावा/एंड्रॉइड क्लास है:

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); 
    } 

} 

क्या किसी के पास कोई विचार है? मैं इस दिन फंस गया हूँ। मुझे लगता है क्योंकि मुझे रुबी के बारे में ज्यादा जानकारी नहीं है, मैं या तो (1) अनुरोध को खराब कर रहा हूं; या (2) मैंने बेस 64 छवि को कैरियरवेव के साथ गलत तरीके से कार्यान्वित किया है।

उत्तर

19

अंत में समस्या हल हो गई! मुझे आशा है कि यह उत्तर उन लोगों को मदद करेगा जो इस समस्या को हल करने की कोशिश कर रहे हैं क्योंकि इसके लिए कोई अच्छा संसाधन नहीं है। यह आश्चर्य की बात थी क्योंकि मुझे लगा कि दूसरों को ऐसा करना चाहता था। कैरियरवेव में मेरा मूल परिवर्तन प्रारंभिक फ़ाइल एक मृत अंत प्रतीत होता है।

नियंत्रक में अपलोड की गई छवि ऑब्जेक्ट को बनाने के लिए यह नीचे आया था और फिर इसे पैराम में वापस इंजेक्शन दे रहा था।

इस विशिष्ट उदाहरण के लिए, हम बेस 64 फ़ाइल ले रहे हैं (जो मुझे लगता है कि आपके पास है, क्योंकि JSON एम्बेडेड फ़ाइलों का समर्थन नहीं करता है) और सिस्टम में एक temp फ़ाइल के रूप में सहेज रहा है, तो हम उस अपलोड किए गए फ़ाइल ऑब्जेक्ट को बना रहे हैं और अंत में इसे पैराम में फिर से डालना।

picture {:user_id => "1", :folder_id => 1, etc., :picture_path {:file => "base64 awesomeness", :original_filename => "my file name", :filename => "my file name"}} 

यहाँ मेरी नियंत्रक अब कैसा दिखता है:

क्या मेरी json/पैरामीटर की तरह लग रहा

40  # POST /pictures 
41 # POST /pictures.json 
42 def create 
43 
44  #check if file is within picture_path 
45  if params[:picture][:picture_path]["file"] 
46   picture_path_params = params[:picture][:picture_path] 
47   #create a new tempfile named fileupload 
48   tempfile = Tempfile.new("fileupload") 
49   tempfile.binmode 
50   #get the file and decode it with base64 then write it to the tempfile 
51   tempfile.write(Base64.decode64(picture_path_params["file"])) 
52  
53   #create a new uploaded file 
54   uploaded_file = ActionDispatch::Http::UploadedFile.new(:tempfile => tempfile, :filename => picture_path_params["filename"], :original_filename => picture_path_params["original_filename"]) 
55  
56   #replace picture_path with the new uploaded file 
57   params[:picture][:picture_path] = uploaded_file 
58  
59  end 
60 
61  @picture = Picture.new(params[:picture]) 
62 
63  respond_to do |format| 
64  if @picture.save 
65   format.html { redirect_to @picture, notice: 'Picture was successfully created.' } 
66   format.json { render json: @picture, status: :created, location: @picture } 
67  else 
68   format.html { render action: "new" } 
69   format.json { render json: @picture.errors, status: :unprocessable_entity } 
70  end 
71  end 
72 end 

केवल एक चीज है इस बिंदु पर करने के लिए छोड़ दिया tempfile नष्ट करने के लिए है, जो मुझे विश्वास है कि tempfile.delete

मुझे उम्मीद है कि यह आपके प्रश्न के साथ मदद करता है! मैंने पूरे दिन कल एक समाधान की तलाश में बिताया, और जो कुछ मैंने देखा है वह एक मृत अंत है। हालांकि, यह मेरे परीक्षण मामलों पर काम करता है।

+1

यह बहुत अच्छा काम किया! इसके लिए धन्यवाद। मैंने पैरा को प्रोसेसिंग को 'pre_filter: process_attached_file में डालने के लिए समाप्त कर दिया, केवल:: बनाएं विधि क्लीनर को बनाए रखने में मदद के लिए कॉल करें। –

+3

मैं वही काम करने की कोशिश कर रहा हूं; क्या आप अपने एंड्रॉइड ऐप के लिए अपना अंतिम जावा कोड पोस्ट कर सकते हैं? – scientiffic

+0

क्या आप एंड्रॉइड पक्ष पर अपलोड मज़े के लिए अपना अंतिम कार्यान्वयन साझा करना चाहते हैं? मैंने एक समान काम किया है और मैं रेल का भी उपयोग कर रहा हूं लेकिन वास्तविक अपलोड अविश्वसनीय रूप से धीमा है - मुझे लगता है कि ऐसा इसलिए है क्योंकि मैं वीब्रिक पर परीक्षण कर रहा हूं, लेकिन मुझे यह देखने के लिए उत्सुकता होगी कि क्या आपने छवि को घटाया है या संकल्प घटाया है या नहीं अपलोड करने से पहले किसी भी तरह से – Riptyde4

संबंधित मुद्दे