Android開發:獲得相簿圖片、拍照、照片上傳伺服器、從伺服器讀取照片

來源:互聯網
上載者:User

標籤:

文章目錄

  • 一 整體功能描述
  • 二 功能實現
    • 1 獲得圖片
    • 2上傳到伺服器並儲存
    • 3從伺服器中獲得圖片並顯示
    • 4Common類中的協助工具輔助

一. 整體功能描述

通過從相簿中選擇圖片或者拍照的方式獲得圖片,然後將這個圖片上傳至伺服器,同時實現從伺服器上讀取該圖片。

二. 功能實現 1.1 獲得圖片

(1)通常情況下,有以下兩種方式:

  • 從相簿中選擇圖片
    這種方式原理比較簡單,就是從SDK中獲得照片,轉成位元組再生產Bitmap對象用於顯示即可。

  • 拍照獲得圖片
    拍照擷取的圖片原理就是先拍照儲存,然後再讀取,就和從相簿中選擇圖片的原理一樣了。

(2)實現:
下面是實現該功能的代碼,由於某種不知名的原因,拍照獲得圖片的方式一直存在問題:無法載入此圖片。解決解決,始終無法解決,就暫且擱下了。本文的重點還是放在了第二部分,關於上傳到伺服器,第一部分還需要進一步完善,關於圖片的選擇和處理,推薦一葉飄舟的文章。

  • 首先是點擊頭像彈出一個dialog供選擇讀入圖片的方式:
 private    CharSequence []its = {"拍照","從相簿選擇"}; //上傳頭像 headImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {     new AlertDialog.Builder(ModiUserInfoActivity.this)                    .setTitle("更換頭像")                    .setItems(its, new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                     Intent intent = new Intent();                    switch (which)                    {                        case 0://拍照,沒有實現的部分,暫時就不貼代碼了,其實暗想應該不難,但是問題卻一直不能解決。                            break;                        case 1://從相簿選擇                            intent.setAction(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT                            intent.addCategory(Intent.CATEGORY_OPENABLE);                            intent.setType("image/*");                            //intent.putExtra("return-data", true);//返回資料                            //intent.putExtra("crop", "true");//裁剪                            startActivityForResult(intent,SELECT_PIC);//啟動activity,重寫onActivityResult擷取結果                            break;                                }                            }                        })                        .create()                        .show();            }        });    }
  • 然後就是對圖片資料進行處理了
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {   if (resultCode != RESULT_OK)       return;       switch (requestCode)       {           case SELECT_PIC://相簿              // ContentResolver resolver = getContentResolver();              //照片的原始資源地址              // Uri originalUri = data.getData();              // Log.i("originalUri",originalUri+"");              Bitmap photo = null;              // try              // {              photo = data.getParcelableExtra("data");              //photo = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));               if(photo!=null)               {                   headImage = Common.zoomBitmap(photo, 85, 85);//進行了縮放,可以忽視                   UserController.updateHeadImage(userId, headImage, handler);//上傳伺服器更新,後面貼代碼                   photo.recycle();//回收               }                   //headImageView.setImageBitmap(headImage);            /*   }catch (IOException e) {                   e.printStackTrace();               }*/               break;           case SELECT_CAMERA://相機,下面代碼寫了不少,但是一直存在問題~               try {                   // 啟動gallery去剪輯這個照片                   //final Intent intent = Common.getCropImageIntent(Uri.fromFile(photoFile));                   //startActivityForResult(intent, SELECT_PIC);                   Intent intent = new Intent("com.android.camera.action.CROP"); //剪裁                   intent.setDataAndType(photoFile, "image/*");                   intent.putExtra("scale", true);                    //設定寬高比例                   intent.putExtra("aspectX", 1);                   intent.putExtra("aspectY", 1);                   intent.putExtra("outputX", 80);                   intent.putExtra("outputY", 80);                   intent.putExtra(MediaStore.EXTRA_OUTPUT, photoFile);                   //Toast.makeText(ModiUserInfoActivity.this, photoFile.toString(), Toast.LENGTH_SHORT).show();                   //廣播重新整理相簿                    Intent intentBc = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);                    intentBc.setData(photoFile);                    this.sendBroadcast(intentBc);                    startActivityForResult(intent, CROP_PHOTO); //設定裁剪參數顯示圖片至ImageView               } catch (Exception e) {                   e.printStackTrace();               }               break;           case CROP_PHOTO:               try {                   //圖片解析成Bitmap對象                   Bitmap bitmap = BitmapFactory.decodeStream(                           getContentResolver().openInputStream(photoFile));                   //Toast.makeText(ModiUserInfoActivity.this, imageUri.toString(), Toast.LENGTH_SHORT).show();                   headImage = Common.zoomBitmap(bitmap, 85, 85);                   UserController.updateHeadImage(userId, headImage, handler);               } catch(FileNotFoundException e) {                   e.printStackTrace();               }               break;           default:               break;       }    }

ok,按照上面的代碼,從相簿選擇照片加裁剪是沒有問題了,至於對圖片的一些處理,可以參考一葉飄舟的博文。

1.2上傳到伺服器並儲存

查閱了很多資料,使用的方式要麼都是那種上傳檔案那類看起來就特別複雜的方式,看的我真的頭大了。後來找了好幾個版本自己都沒能成功實現把1.1中擷取的圖片上傳到伺服器。後來回想了一下http請求不就是傳送的位元組嘛,那我把圖片轉成位元組不就能傳過去了麼,另一個問題又來了,有時候我們並不是單單傳送一張圖片過去,可能還有其他資訊,比如一個表單或者一個id之類的,總之要傳送的資料還有不僅僅是圖片。之前傳送資料都是通過json或者map轉成String再轉成byte[]實現的,那麼現在傳送的是圖片+其他資料,思路便是:圖片->String,然後和其他資料一起打包成json->String->byte[]->Bitmap。

  • 用戶端
    現在接著寫1.1中代碼使用到的UserController.updateHeadImage(userId, headImage, handler)。
/** * 儲存頭像 * @param userId * @param handler * @param image */ public static void updateHeadImage(final String userId,final Bitmap image, final Handler handler) {     new Thread()        {            @Override            public void run()            {                JSONObject jsonObject = new JSONObject();                try {                    jsonObject.put("userId",userId);                    //將Bitmap轉成String,其實這是一個加密過程。後面會有Common.Bitmap2String()的代碼。                    jsonObject.put("userImageContent", Common.Bitmap2String(image));                    String content = String.valueOf(jsonObject);                    /**                     * 請求地址                     */                    String url =  ConfigModel.getServerURL()+"user/updateImage";                    String result = Common.httpPost(url,content);//post請求伺服器:資料content,請求路徑url。這個函數也是自己寫在Common類裡,其實就是稍微封裝了一下post請求的過程,方便複用。                    Log.i("result",result);                    /**                     * 伺服器返回結果                     * 繼續幹什麼事情....                     */                    Message message = new Message();                    Bundle bundle = new Bundle();                    bundle.putString("result",result);                    message.setData(bundle);                    message.what = R.id.save_user_image_result;                    handler.sendMessage(message);                }catch (Exception e){}            }        }.start();    }
  • 伺服器端
    用戶端將圖片加密成了String,那麼服務端就需要解碼就可以獲得圖片。
//第一步,將資料流轉String,自己封裝成了一個read函數,方便複用;String streamIn = ReadStream.read(new BufferedInputStream(request.getInputStream()));//JSONObject object = JSONObject.fromObject(streamIn).getJSONObject("user");JSONObject object = JSONObject.fromObject(streamIn);//String轉JSONString userId = object.getString("userId");String userImageContent = object.getString("userImageContent");//獲得映像的資料//..其他步驟省略//..比如判斷是否是新映像,比如產生映像ID imgId = Tool.getUUID();//第二步將映像資料String轉成Bitmapbyte[] bitmapArray= Base64.decode(imageContent);try{    File imageFile = new File(headImagePath);      if(!imageFile.exists())        imageFile.mkdirs();        //建立輸出資料流      FileOutputStream outStream = new FileOutputStream(imageFile.getPath()+"\\"+imgId+".png");          //寫入資料      outStream.write(bitmapArray);          //關閉輸出資料流      outStream.close();             }catch(IOException e){    System.out.println(e);}

由此就完美的將用戶端的映像和資料都上傳到伺服器上了。下面部分就是從伺服器上獲得圖片和資料再返回給用戶端,有了前面部分的思路,那這部分就很容易實現,反其道而行之就可以了。

1.3從伺服器中獲得圖片並顯示
  • 伺服器端
    伺服器端要做的事情就是將Bitmap轉成String,然後和其他資料打包成json,返回給用戶端。
//讀取圖片,轉成String    public static String readImage(String imgId)    {        //byte []data = imageContent.getBytes();        File file = new File(headImagePath+imgId+".png");        try {            FileInputStream inputStream = new FileInputStream(file);            byte[] bitmapArray = new byte[(int) file.length()];            inputStream.read(bitmapArray);            inputStream.close();            return Base64.encode(bitmapArray);        } catch(Exception e)        {            return "";        }    }    //*****************************************    //代碼片.....和上面的代碼不在同一個java檔案中    //*****************************************    /**     * 查詢一個user     *      * @param userId     *            主鍵     * @return user     */    @RequestMapping(value = "/user/get/{id}")    @ResponseBody    public JSONObject get(@PathVariable("id") String userId,            HttpServletResponse response) {        response.setHeader("Access-Control-Allow-Origin", "*");        User user = userDAO.getUser(userId);        JSONObject jsonObject = new JSONObject();        jsonObject.put("user", user);        if(user.getUserImage()!=null&&!"".equals(user.getUserImage()))        {               jsonObject.put("userImageContent", Tool.readImage(user.getUserImage()));        }        return jsonObject;    }
  • 用戶端
    這部分我就不貼代碼了,因為自己把很多功能都封裝了,要貼出來有點麻煩,總之此時的圖片資料已經轉成了String,只需要在顯示的時候,再轉成Bitmap。String->Bitmap的實現請參考我的Common類。
1.4Common類中的協助工具輔助
 /**     * 映像轉位元組     * @param bm     * @return     */    public static byte[] Bitmap2Bytes(Bitmap bm) {        ByteArrayOutputStream baos = new ByteArrayOutputStream();        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);        return baos.toByteArray();    }    /**     * 映像轉String     * @param bitmap     * @return     */    public static String Bitmap2String(Bitmap bitmap)    {        return Base64.encodeToString(Bitmap2Bytes(bitmap), Base64.DEFAULT);    }    /**     * string轉成bitmap     *     * @param st     */    public static Bitmap String2Bitmap(String st)    {        Bitmap bitmap = null;        try        {            byte[] bitmapArray;            bitmapArray = Base64.decode(st, Base64.DEFAULT);            bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);            return bitmap;        }        catch (Exception e)        {            return null;        }    }

OK,最後大功告成,後面再解決拍照、以及圖片處理的問題!

Android開發:獲得相簿圖片、拍照、照片上傳伺服器、從伺服器讀取照片

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.