gpt4 book ai didi

java - Android - 从磁盘上传图像

转载 作者:行者123 更新时间:2023-11-30 11:43:02 25 4
gpt4 key购买 nike

我在 Android 上上传文件时遇到了一些问题。我已经将应用程序的这一部分拼凑在一起,现在需要进行一些修改。

我正在尝试从 Uri 引用的磁盘图像上传文件到服务器。

在上传之前,我尝试将图像缩小到最大尺寸 1280。

这是一个示例类,其中包含我正在使用的实际代码。我敢肯定这是非常低效的:

/**
* This is a fake class, this is actually spread across 2 or 3 files
*/
public class Temp
{
/**
* This is used to return an Input stream of known size
*/
public static class KnownSizeInputStream extends InputStreamBody
{
private int mLength;

public KnownSizeInputStream( final InputStream in, final int length, final String mimeType, final String filename )
{
super( in, mimeType, filename );
mLength = length;
}

public long getContentLength()
{
return mLength;
}
}

private static final int MAX_WIDTH = 1280;
private static final int MAX_HEIGHT = 1280;

/**
* Open up a file on disk and convert it into a stream of known size
*/
public KnownSizeInputStream toStreamAio( Context c, Uri path )
{
/**
* Scale down bitmap
*/
Bitmap bitmapData = null;

try
{
bitmapData = BitmapFactory.decodeStream( c.getContentResolver().openInputStream( path ) );
}
catch( Exception e )
{
e.printStackTrace();
}

int imgWidth = bitmapData.getWidth();
int imgHeight = bitmapData.getHeight();

// Constrain to given size but keep aspect ratio
float scaleFactor = Math.min( ( ( float )MAX_WIDTH ) / imgWidth, ( ( float )MAX_HEIGHT ) / imgHeight );

Matrix scale = new Matrix();
scale.postScale( scaleFactor, scaleFactor );
final Bitmap scaledImage = Bitmap.createBitmap( bitmapData, 0, 0, imgWidth, imgHeight, scale, false );

try
{
bitmapData = scaledImage.copy( scaledImage.getConfig(), true );

scaledImage.recycle();
}
catch( Exception e )
{
e.printStackTrace();
}

/**
* To byte[]
*/
byte[] byteData = null;

ByteArrayOutputStream baos = new ByteArrayOutputStream();

bitmapData.compress( Bitmap.CompressFormat.JPEG, 100, baos );

byteData = baos.toByteArray();

/**
* To stream
*/
return new KnownSizeInputStream( new ByteArrayInputStream( byteData ), byteData.length, "image/jpg", "Some image" );
}

/**
* Some pieces are removed, the main part is the addPart line
*/
public void doUpload()
{
// create a new HttpPost, to our specified URI
HttpPost post = new HttpPost( postUri );

// org.apache.http.entity.mime
MultipartEntity entity = new MultipartEntity( HttpMultipartMode.STRICT );


// This line starts all of the issues
entity.addPart( "file", toStreamAio( mContext, Uri.parse( "/some/file.jpg" ) ) );


post.setEntity( entity );

// send it
HttpResponse response = client.execute( post );

}
}

这是我遇到的异常,我从尝试分配图像的完整大小的调整大小中猜测:

Caused by: java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCopy(Native Method)
at android.graphics.Bitmap.copy(Bitmap.java:403)
at com.app.helper.UploadableImage.toScaledBitmap(UploadableImage.java:170)
at com.app.helper.UploadableImage.toByteArray(UploadableImage.java:53)
at com.app.helper.UploadableImage.toStream(UploadableImage.java:242)
at com.app.rest.task.UploadContentTask.doInBackground(UploadContentTask.java:80)
at com.app.rest.task.UploadContentTask.doInBackground(UploadContentTask.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 5 more

它是由这条线触发的:

data = scaledImage.copy( scaledImage.getConfig(), true );

我想我要问的主要问题是,如何从磁盘上的路径获取图像、缩放图像,以及我可以放入的流:

org.apache.http.entity.mime.MultipartEntity

通过:

.addPart("file", streamData);

最有效的,假设图像可以是巨大的(~6000px 是我迄今为止达到的最大尺寸)

最佳答案

首先,为什么要复制缩放后的位图?你不能像这样直接压缩缩放后的位图吗:

final Bitmap scaledImage = Bitmap.createBitmap(bitmapData, 0, 0,
imgWidth, imgHeight, scale, false);
scaledImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);

如果可以避免复制,则可以避免出现 OutOfMemoryError

即使您使用 JPEG 压缩选择 95% 的质量(处理自然物体的照片时),您也可以获得良好的压缩效果,质量损失微乎其微。您应该尝试质量设置并自行检查。

关于java - Android - 从磁盘上传图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11435278/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com