Xamarin forms android映像未被压缩

Xamarin forms android映像未被压缩,android,xamarin,xamarin.android,android-bitmap,bitmapfactory,Android,Xamarin,Xamarin.android,Android Bitmap,Bitmapfactory,我在做xamarin表单项目。我正在从图库中拍摄图像并将其上传到服务器。我的后端是解析后端,我们不能上传大小超过1MB的文件。所以,我试图压缩图像,这样每次图像大小都小于1MB。 以下是我的代码:- protected override async void OnActivityResult (int requestCode, Result resultCode, Intent intent) { if (resultCode == Result.Canceled)

我在做xamarin表单项目。我正在从图库中拍摄图像并将其上传到服务器。我的后端是解析后端,我们不能上传大小超过1MB的文件。所以,我试图压缩图像,这样每次图像大小都小于1MB。 以下是我的代码:-

protected override async void OnActivityResult (int requestCode, Result resultCode, Intent intent)
    {
        if (resultCode == Result.Canceled)
            return;

        try {
            var mediafile = await intent.GetMediaFileExtraAsync (Forms.Context);

            // get byte[] from file stream
            byte[] byteData = ReadFully (mediafile.GetStream ());

            byte[] resizedImage = ResizeAndCompressImage (byteData, 60, 60, mediafile);

            var imageStream = new ByteArrayContent (resizedImage);
            imageStream.Headers.ContentDisposition = new ContentDispositionHeaderValue ("attachment") {
                FileName = Guid.NewGuid () + ".Png"
            };

            var multi = new MultipartContent ();
            multi.Add (imageStream);
            HealthcareProfessionalDataClass lDataClass = HealthcareProfessionalDataClass.Instance;
            lDataClass.Thumbnail = multi;
            App.mByteArrayOfImage = byteData;

            MessagingCenter.Send<IPictureTaker,string> (this, "picturetaken", mediafile.Path);
        } catch (InvocationTargetException e) {
            e.PrintStackTrace ();
        } catch (Java.Lang.Exception e) {
            e.PrintStackTrace ();
        }
    }

public static byte[] ReadFully (System.IO.Stream input)
    {
        using (var ms = new MemoryStream ()) {
            input.CopyTo (ms);
            return ms.ToArray ();
        }
    }


public static byte[] ResizeAndCompressImage (byte[] imageData, float width, float height, MediaFile file)
    {
        try {
            // Load the bitmap
            var options = new BitmapFactory.Options ();
            options.InJustDecodeBounds = true;
            options.InMutable = true;
            BitmapFactory.DecodeFile (file.Path, options);
            // Calculate inSampleSize
            options.InSampleSize = calculateInSampleSize (options, (int)width, (int)height);
            // Decode bitmap with inSampleSize set
            options.InJustDecodeBounds = false;

            var originalBitMap = BitmapFactory.DecodeByteArray (imageData, 0, imageData.Length, options);

            var resizedBitMap = Bitmap.CreateScaledBitmap (originalBitMap, (int)width, (int)height, false);

            if (originalBitMap != null) {
                originalBitMap.Recycle ();
                originalBitMap = null;
            }
            using (var ms = new MemoryStream ()) {

                resizedBitMap.Compress (Bitmap.CompressFormat.Png, 0, ms);

                if (resizedBitMap != null) {
                    resizedBitMap.Recycle ();
                    resizedBitMap = null;
                }
                return ms.ToArray ();
            }
        } catch (Java.Lang.Exception e) {
            e.PrintStackTrace ();
            return null;
        }
    }

public static int calculateInSampleSize (BitmapFactory.Options options, int reqWidth, int reqHeight)
    {
        // Raw height and width of image
        int height = options.OutHeight;
        int width = options.OutWidth;
        int inSampleSize = 16;

        if (height > reqHeight || width > reqWidth) {

            int halfHeight = height / 2;
            int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                   && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }
activityresult上的受保护重写异步void(int-requestCode、Result-resultCode、Intent-Intent)
{
if(resultCode==Result.cancelled)
返回;
试一试{
var mediafile=await intent.getmediafileextrasync(Forms.Context);
//从文件流获取字节[]
byte[]byteData=ReadFully(mediafile.GetStream());
byte[]resizedImage=ResizeAndCompressImage(byteData,60,60,mediafile);
var imageStream=新的ByteArrayContent(resizedImage);
imageStream.Headers.ContentDisposition=新的ContentDispositionHeaderValue(“附件”){
FileName=Guid.NewGuid()+“.Png”
};
var multi=新的MultipartContent();
multi.Add(imageStream);
HealthcareProfessionalDataClass lDataClass=HealthcareProfessionalDataClass.Instance;
lDataClass.Thumbnail=multi;
App.mbyteraryofimage=字节数据;
Send(这是“picturetaken”,mediafile.Path);
}捕获(调用TargetException e){
e、 PrintStackTrace();
}catch(Java.Lang.e异常){
e、 PrintStackTrace();
}
}
公共静态字节[]已就绪(System.IO.Stream输入)
{
使用(var ms=newmemoryStream()){
input.CopyTo(ms);
返回ms.ToArray();
}
}
公共静态字节[]大小和压缩图像(字节[]图像数据、浮动宽度、浮动高度、媒体文件)
{
试一试{
//加载位图
var options=new-BitmapFactory.options();
options.InJustDecodeBounds=true;
options.InMutable=true;
BitmapFactory.DecodeFile(file.Path,选项);
//计算样本大小
options.InSampleSize=计算样本大小(选项,(int)宽度,(int)高度);
//使用inSampleSize集合解码位图
options.InJustDecodeBounds=false;
var originalBitMap=BitmapFactory.DecodeByteArray(imageData,0,imageData.Length,选项);
var resizedBitMap=Bitmap.CreateScaledBitmap(originalBitMap,(int)宽度,(int)高度,false);
if(originalBitMap!=null){
originalBitMap.Recycle();
originalBitMap=null;
}
使用(var ms=newmemoryStream()){
resizedBitMap.Compress(Bitmap.CompressFormat.Png,0,ms);
if(resizedBitMap!=null){
resizedBitMap.Recycle();
resizedBitMap=null;
}
返回ms.ToArray();
}
}catch(Java.Lang.e异常){
e、 PrintStackTrace();
返回null;
}
}
公共静态int-calculateInSampleSize(BitmapFactory.Options选项、int-reqWidth、int-reqHeight)
{
//图像的原始高度和宽度
int height=options.OutHeight;
int width=options.OutWidth;
int inSampleSize=16;
如果(高度>要求高度| |宽度>要求宽度){
int halfHeight=高度/2;
int halfWidth=宽度/2;
//计算最大的inSampleSize值,该值为2的幂次方,并同时保持这两个值
//高度和宽度大于请求的高度和宽度。
而((半高/采样)大于所需高度
&&(半宽/采样尺寸)>reqWidth){
inSampleSize*=2;
}
}
返回样本大小;
}
但问题是我的图像没有被压缩。我无法上传大小为2MB的图像,我想上传大小至少为30MB的图像。我还注意到calculateInSampleSize总是返回16作为inSampleSize,这是默认值


如果我的代码中有任何问题,请告诉我。

这似乎是一种非常复杂的方法。下面是一个更简洁的示例,可以帮助您调整图像大小:

protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    var stream = this.Resize(data.Data, 60, 60);
    // Send the stream to Parse
}

private Stream Resize(Android.Net.Uri uri, float maxWidth, float maxHeight)
{
    var scale = 1;
    using (var rawStream = this.ContentResolver.OpenInputStream(f))
    using (var options = new BitmapFactory.Options { InJustDecodeBounds = true })
    {
        BitmapFactory.DecodeStream(rawStream, null, options);

        while(options.OutWidth / scale / 2 > maxWidth || 
              options.OutHeight / scale / 2 > maxHeight)
        {
            scale *= 2;
        }
    }

    using (var options = new BitmapFactory.Options { InSampleSize = scale })
    using (var bitmap = f.GetBitmap(options))
    {
        var memoryStream = new MemoryStream();
        bitmap.Compress(Bitmap.CompressFormat.Png, 0, memoryStream);
        memoryStream.Position = 0;

        return memoryStream;
    }
}
关于为什么会看到
InSampleSize=16
,我的猜测是图像的高度或宽度小于1920(即
60*2*16
),并且由于您在while循环中使用
&&
,对该侧的更大检查失败,因此,您永远不会进入while主体


此外,如果您希望创建较小的图像,将其压缩为Jpeg比使用png要好得多。

我认为这将有助于管理和压缩较大的图像,如果不是,请原谅