3

我想添加上传图片大小的限制(目前图片上传到服务器)

当有人从 SD 卡获取图像或从相机捕获图像时,我想向用户显示它上传的最大文件大小的消息 - 即 500kb 或者我可以将图像调整为更小的尺寸。例如,将 1mb 图像调整为 400-500kb(如 Facebook)。

这是我从 SD 卡获取图像或从相机捕获图像后实现的示例代码。

 FileConnection file = (FileConnection)Connector.open(url);
 if(file.exists())
 {
     try{
         String fileName = url .substring(url.lastIndexOf('/') + 1);
         //String fileName = url ;
         Dialog.alert("fileName  " + fileName);
         InputStream inputStream = file.openInputStream();

         ByteArrayOutputStream bos=new ByteArrayOutputStream();
         int buffersize=1024;
         byte[] buffer=new byte[buffersize];
         int length=0;
         while((length=inputStream.read(buffer))!=-1)
         {
             bos.write(buffer,0,length);
         }
         byte[] imagedata=bos.toByteArray();
         Dialog.alert("Url  " + Url  + " Image Data Byte " + imagedata);
         HttpConnection conn = (HttpConnection) Connector.open(Url, Connector.READ_WRITE);
         conn.setRequestMethod(HttpConnection.POST);
         String boundary = "Some_Unique_Text_Also_Alphanumeric";
         conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_TYPE,                    
             HttpProtocolConstants.CONTENT_TYPE_MULTIPART_FORM_DATA
                                 + ";boundary=" + boundary);

             conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH,
                         String.valueOf(imagedata.length));
         conn.setRequestProperty("x-rim-transcode-content", "none");

         ByteArrayOutputStream out = new ByteArrayOutputStream();
         OutputStream finalOut = conn.openOutputStream();

         String newLine = "\r\n";
         out.write(newLine.getBytes());
         out.write("--".getBytes());
         out.write(boundary.getBytes());
         out.write(newLine.getBytes());
         String contDisp = "Content-Disposition:form-data;name=\"image\";fileName=\"Image.jpg\"";
         String contEnc = "Content-Transfer-Encoding: binary";
         String contentType = "Content-Type:image/jpeg";
         out.write(contDisp.getBytes());
         out.write(newLine.getBytes());
         out.write(contentType.getBytes());
         out.write(newLine.getBytes());
         out.write(contEnc.getBytes());
         out.write(newLine.getBytes());
         out.write(newLine.getBytes());
         out.write(imagedata);
         out.write(newLine.getBytes());
         out.write("--".getBytes());
         out.write(boundary.getBytes());
         out.write("--".getBytes());
         out.write(newLine.getBytes());
         finalOut.write(out.toByteArray());

         out.flush();
         out.close();

         finalOut.flush();
         finalOut.close();
         InputStream instream=conn.openInputStream();
         int ch=0;
         StringBuffer buffesr=new StringBuffer();
         while((ch=instream.read())!=-1)
         {
             buffesr.append((char)ch);
             Dialog.alert("Uploaded");
         }
     }
     catch (Exception e) {

         Dialog.alert("Exception " + e);
     }   
 }

有什么帮助吗??

4

1 回答 1

5

问题在于,对于相机图片,您无法预测以字节为单位的特定大小对应的物理图像大小(像素宽度 x 高度) 。

如果您对可以上传的大小(以字节为单位)有严格的固定限制,则可能需要执行以下操作:

  • 尝试几张图像,并找到一个近似的图像大小(宽 x 高),它会生成一个通常适合 400-500KB 限制的 JPG 文件

  • 在您的应用程序中,将相机图像调整为该物理尺寸(宽 x 高,以像素为单位)

  • 检查新 JPG 数据的大小,看看它是否符合您的限制

  • 如果不合适,则必须将原始图像重新缩放为较小的尺寸

如您所见,这并不是那么简单。我见过的大多数服务器(例如Facebook)都会告诉您图像可以达到的最大物理尺寸(以像素为单位)(例如,最宽尺寸为 960 像素……宽度或高度)。如果这对您的服务器来说足够好,那么在 BlackBerry 客户端编写代码会容易得多。

限制为固定像素宽度和高度

你可以使用这样的东西:

FileConnection file;
InputStream inputStream;

try {
    file = (FileConnection) Connector.open(url);  // JPG file:// URL
    if (file.exists())
    {
        inputStream = file.openInputStream();           
        byte[] data = IOUtilities.streamToBytes(inputStream);

        Bitmap original = Bitmap.createBitmapFromBytes(data, 0, data.length, 1);

        Bitmap scaledImg = new Bitmap(640, 480);    // maximum width and height
        original.scaleInto(scaledImg, 
                           Bitmap.FILTER_LANCZOS,   /* LANCZOS is for best quality */
                           Bitmap.SCALE_TO_FIT);  

        // http://stackoverflow.com/a/14147236/119114
        int jpegQuality = 85;
        EncodedImage encodedImg = JPEGEncodedImage.encode(scaledImg, jpegQuality);
        byte[] imageData = encodedImg.getData(); 
        // TODO: send imageData as you already were       
    }
} catch (Exception e) {
    // log exception
} finally {
    try {
        if (file != null) {
            file.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }
    } catch (IOException ioe) {
        // nothing can be done here
    }
}

当然,您应该在后台线程上执行所有这些工作。一旦你知道了最终的图像大小,如果你真的想要,你可以通过以下方式通知用户:

final uploadSizeKb = imageData.length / 1024;
UiApplication.getUiApplication().invokeLater(new Runnable() {
   public void run() {
      Dialog.alert(uploadSizeKb + "KB uploaded to server");
   }
});

进一步优化

正如您可能知道的那样,您可以使用此算法进行一些调整:

  • 在尝试缩放之前,您可以通过检查图像文件是否已经足够小来进行优化。(检查file.fileSize()

  • 您可以使用Bitmap.FILTER_BILINEARorBitmap.FILTER_BOX代替Bitmap.FILTER_LANCZOS.

  • 当您转换回 JPEG 进行上传时,您可以将 JPEG 品质因数从 85 更改

  • 您可能需要检查图像方向以避免在使用SCALE_TO_FIT. 如果相机图像方向错误,只需切换scaledImg位图宽度和高度(例如 640x480 -> 480x640)

  • 实际上,您可以跳过几个步骤,并在读取图像文件时直接缩放,使用createBitmapFromBytes(). 最后一个参数是比例参数。不幸的是,由于照片都是不同的,因此也很难选择一种可行的比例。正如我所说,服务器简单地指定最大图像大小(以像素为单位)更为常见。

操作系统 < 5.0 支持

如果您在 OS 5.0 中没有可用的图像缩放 API,那么这个较旧的工具包可能会很有用

于 2013-05-31T10:31:24.017 回答