【问题标题】:Uploading multiple images to server上传多张图片到服务器
【发布时间】:2013-01-12 02:06:03
【问题描述】:

用户可以通过相机在android端拍摄5-6张照片。所以,我使用了 ACTION_IMAGE_CAPTURE。在 onActivityResult 我这样做是为了收集相机拍摄的图像的位图。假设第一张照片和第二张照片如下。

if(requestCode == 1)
{
    bitMap1 = (Bitmap)extras.get("data");
    imageView1.setImageBitmap(bitMap1);
    globalvar = 2;
}
if(requestCode == 2)
{
    bitMap1 = (Bitmap)extras.get("data");
    imageView2.setImageBitmap(bitMap2);
    globalvar = 2;
}

要将这些图像发送到 php 服务器,我执行以下操作..

protected String doInBackground(Integer... args) {
            // Building Parameters


    ByteArrayOutputStream bao1 = new ByteArrayOutputStream();
    bitMap1.compress(Bitmap.CompressFormat.JPEG, 90, bao1);
    byte [] bytearray1 = bao1.toByteArray();
    String stringba1 = Base64.encode(bytearray1);


 ByteArrayOutputStream bao2 = new ByteArrayOutputStream();
    bitMap2.compress(Bitmap.CompressFormat.JPEG, 90, bao2);
    byte [] bytearray2 = bao2.toByteArray();
    String stringba2 = Base64.encode(bytearray2);


            String parameter1 = "tenant";
                String parameter2 = "price";

            List<NameValuePair> params = new ArrayList<NameValuePair>();

                params.add(new BasicNameValuePair("person",parameter1));
                params.add(new BasicNameValuePair("price",parameter2));
                params.add(new BasicNameValuePair("image1",stringba1));
                params.add(new BasicNameValuePair("image2",stringba2));

            JSONObject json = jParser.makeHttpRequest(requiredurl, "POST", params);


            Log.d("Details", json.toString());



                int success = json.getInt("connected");

                if (success == 1) {

                    //blah blah
                      }
        }

这里是 ma​​keHttpRequest() 方法

public JSONObject makeHttpRequest(String url, String method,
            List<NameValuePair> params) {

        // Making HTTP request
        try {

            // check for request method
            if(method == "POST"){

                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);
                httpPost.setEntity(new UrlEncodedFormEntity(params));

                HttpResponse httpResponse = httpClient.execute(httpPost);

                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();

            }       

       ................
       ....................... // Here the result is extracted and made it to json object
       .............................

        // return JSON 
        return jObj;  // returning the json object to the method that calls.

    }

下面是sn-p的php代码:

$name = $_POST[person];
$price = $_POST[price];
$binary1 = base64_decode($image2);
$binary2 = base64_decode($image2);

$file1 = tempnam($uploadPath, 'image2');
$fp1  = fopen($file1, 'wb');
fwrite($fp1, $binary1);
fclose($fp1);
.................
............................

但是我无法将图像存储在服务器端文件夹中。即使我在一些链接中看到说上传多张图片时 Base64 不是可取的方式。有人可以建议我如何进行吗?已经看过this 和许多其他链接,但无法满足我的要求,因为我什至必须发送一些数据(如人名、价格)以及这些图像。非常感谢您对此提供任何帮助。

注意:即使有人可以建议我如何将上面的临时文件($file1)保存在服务器文件夹中,我也会非常感激。

【问题讨论】:

  • 使用标准的 HTTP 帖子。 base64 将数据大小增加了大约 33%。如果您的应用超出了他们的数据上限,您的用户将不会高兴。
  • 你为什么不使用 multipartEntity??
  • @MarcB 我只使用 HttpPost,对吧?它在我的代码中。那么,这不是标准吗?请建议我继续进行的解决方案。我一直在为此苦苦挣扎。
  • 好吧,您不是在进行标准的多部分类型文件上传。
  • @Marc B 分段上传不是默认base64编码的吗?

标签: php android image


【解决方案1】:

您是否考虑过使用 FTP 而不是您目前的方法?有一个来自 apache 的库,称为 Apache 的 commons-net-ftp 库,可以轻松完成这项工作。

Using apache FTP library

这是我很久以前在 stackoverflow 上提出的一个问题。我之前实现了几乎相同的代码,但我发现 FTP 方法更容易将文件上传到服务器。

@TemporaryNickName 如何与该图像一起发送其他数据。此外,我的图像数据是位图,而不是 uri。按照我现在的情况如何实现?

*有很多教程向您展示如何将位图转换为图像文件(这几乎是临时保存文件并在 FTP 完成后立即删除的方法),此外,当您使用默认内置相机应用程序拍照时,您的图像会自动保存。 那么发送数据应该单独完成,在这种情况下,我会编写一个带有 $_POST 的 PHP 脚本来接收数据而不是将其保存到数据库中或将其写入 XML*


要保存上传的文件,请使用

move_uploaded_file($src, $path);

move uploaded file doc

【讨论】:

  • 为您的时间+1。但正如我告诉你的,我还需要发送其他数据。
【解决方案2】:

要发送多种类型的数据,请使用MultipartEntity(来自您问题中提供的链接)而不是URLEncodedEntity。这个想法是MultipartEntity 只包含不同类型的主体(例如StringBodyFileBody 等)。因此,如果您需要以 Base64 格式发送图像,请将它们作为 StringBody 添加到 MultipartEntity(应设置为您的请求的实体,使用 setEntity)。

尽管如此,我强烈建议您将位图保存在磁盘(SD 卡)上并改用FileBody。它将为您节省大量内存(使用 Base64,您必须一次加载所有图像)并且......如果用户在上传时关闭您的应用程序怎么办?您将永远丢失位图。

附:不要忘记使用Service 来上传任务。

【讨论】:

  • 感谢您抽出宝贵时间 +1。好的。我将图像保存在 sd 卡上,然后提供使用 MultipartEntity 的路径,因为如果我仍然使用该 base64 将位图转换为字符串,因为它增加了要发送的数据,那将毫无用处。但是你能告诉我假设如果我做 entity.addPart("myIdentifier", new StringBody("stringvalue")); entity.addPart("myImageFile", new FileBody(imageFile)); entity.addPart("myAudioFile", new FileBody(audioFile));像这样如何在php端获取字符串值(例如,stringvalue)?
  • @Korhan 据我记得文件将在 $_FILES 变量中。在您的情况下,$_FILES["myAudioFile"]["tmp_name"] 将是刚刚上传文件的临时路径(然后您应该将其移至其他地方)。您问题的链接中提供的示例)
  • 是的。我知道那件事。但我问的是字符串。将 $_POST[myIdentifier];给我取字符串值?
  • @Korhan 我不是真正的 php 开发人员,但我假设文件将在 $_FILES 中,是的,其他数据将在 $_POST 中。试试看)
【解决方案3】:

这是我的代码 sn-p,希望对您有所帮助:

private class AsyncTask1 extends AsyncTask<Void, Void, String>{




    @Override
    protected String doInBackground(Void... params) {

        boolean response = false;

        try {

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            FileBody bin = new FileBody(new File("temp"));

            File tempImg  = new File("sdcard/signature.jpg");
            if(tempImg.exists())
            {
                checkimgfile=checkimgfile+"LPA"+tempImg;
                bin = new FileBody(tempImg, "image/jpg");
                reqEntity.addPart("txt_sign_lpa", bin);
                reqEntity.addPart("count_lpa",new StringBody("1"));
            }
            else
            {
                reqEntity.addPart("count_lpa",new StringBody("0"));
            }

                FileBody bin1 = new FileBody(new File("temp"));
                File tempImg1  = new File("sdcard/signature2.jpg");
                if(tempImg1.exists())
                {

                    checkimgfile=checkimgfile+"subject"+tempImg1;
                    bin1 = new FileBody(tempImg1, "image/jpg");
                    reqEntity.addPart("txt_sign", bin1);
                    reqEntity.addPart("count_subject",new StringBody("1"));
                }




                reqEntity.addPart("count",new StringBody("0"));


            reqEntity.addPart("name",new StringBody("Shaili"));
            reqEntity.addPart("age",new StringBody("47"));




            try
            {


            ConnectivityManager cm =
            (ConnectivityManager)getBaseContext().getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();


            if(activeNetwork!=null && activeNetwork.isAvailable() && activeNetwork.isConnected())
            {
                String xml = "";
                HttpParams httpParameters = new BasicHttpParams();  
                HttpConnectionParams.setConnectionTimeout(httpParameters, 100000);
                HttpConnectionParams.setSoTimeout(httpParameters, 100000);
                final HttpClient httpclient = new DefaultHttpClient(httpParameters);
                final HttpPost httppost = new HttpPost("https://www.xyz.com/abc.php");//url where you want to post your data.
                httppost.setParams(httpParameters);


                httppost.setEntity(reqEntity);
                httppost.addHeader("Accept", "text/html");

                httppost.addHeader("Host", "www.xyz.com");
                httppost.addHeader("User-Agent",
                        "Android ");

                HttpResponse response1 = null;
                String errMessage = "Error";
                try {

                    response1 = httpclient.execute(httppost);
                    final HttpEntity resEntity = response1.getEntity();
                    InputStream content = resEntity.getContent();
                    BufferedReader b = new BufferedReader(new InputStreamReader(
                            content));
                    xml = XmlParser.getTrimmedResponse(b);

                    if (response1 != null){
                        if(Integer.toString(response1.getStatusLine().getStatusCode()).equals("200")){
                            return "success";
                        }
                    }



                } catch (Exception e) {


                    e.printStackTrace();
                    errorstring=errorstring+e.getLocalizedMessage();
                    errMessage = "Network error";

                    return errMessage;
                }

            }
            else if(activeNetwork==null)
            {

                return "Available";
            }

            }
            catch(Exception e)
            {

            Toast.makeText(getBaseContext(), "Network Connection not available", 1).show();
            progressDialog.dismiss();

            }


        } catch (Exception e) {

            errorstring=errorstring+e.getLocalizedMessage();
            return "Network error";

        }
        return "abc";
    }       

    protected void onPostExecute(String result) {


    //do your stuff

    }
}

【讨论】:

  • @Payal 为您的时间+1。会检查这个。
  • @Payal 我在 FileBodya 和 StringBody 上遇到错误。可能是什么原因?我还需要添加任何其他内容吗?
猜你喜欢
  • 1970-01-01
  • 2019-03-07
  • 2017-10-25
  • 2015-10-04
  • 2023-03-11
  • 2014-05-31
  • 2018-06-13
  • 1970-01-01
  • 2012-03-11
相关资源
最近更新 更多