2015-09-14 14 views
2

我正在写一个Xamarin表单android应用程序,我正在从库中获取图像。我想上传这些图像到服务器,所以我需要从它的字节[]。我缩放和压缩这些图像,然后从中取出byte []。我的问题是,当我压缩图像时,图像正在改变从纵向到横向的方向。我尝试过使用'ExifInterface'类并更改图像方向,但它不起作用。以下是我的完整代码: -Xamarin形式Android压缩后的图像方向更改

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

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

      byte[] data1 = ReadFully (mediafile.GetStream()); 

      byte[] resizedImage = ResizeImageAndroid (data1, 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 = data1; 

      System.Diagnostics.Debug.WriteLine (mediafile.Path); 

      MessagingCenter.Send<IPictureTaker,string> (this, "picturetaken", mediafile.Path); 
     } 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[] ResizeImageAndroid (byte[] imageData, float width, float height, MediaFile file) 
    { 
     try { 
      // Load the bitmap 

      var options = new BitmapFactory.Options(); 
      options.InJustDecodeBounds = true; 

      // Calculate inSampleSize 
      options.InSampleSize = calculateInSampleSize (options, (int)width, (int)height); 
      // Decode bitmap with inSampleSize set 
      options.InJustDecodeBounds = false; 

      Bitmap originalImage = BitmapFactory.DecodeByteArray (imageData, 0, imageData.Length, options); 
      Bitmap resizedImage = Bitmap.CreateScaledBitmap (originalImage, (int)width, (int)height, false); 


      using (var ms = new MemoryStream()) { 

       resizedImage.Compress (Bitmap.CompressFormat.Png, 0, ms); 
       resizedImage = changeOrientation (file, resizedImage); 

       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 = 4; 

     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; 
    } 

static Bitmap changeOrientation (MediaFile mediafile, Bitmap bitmap) 
    { 
     var exifInterface = new ExifInterface (mediafile.Path); 
     int orientation = exifInterface.GetAttributeInt (ExifInterface.TagOrientation, 0); 
     var matrix = new Matrix(); 
     switch (orientation) { 
     case 2: 
      matrix.SetScale (-1, 1); 
      break; 
     case 3: 
      matrix.SetRotate (180); 
      break; 
     case 4: 
      matrix.SetRotate (180); 
      matrix.PostScale (-1, 1); 
      break; 
     case 5: 
      matrix.SetRotate (90); 
      matrix.PostScale (-1, 1); 
      break; 
     case 6: 
      matrix.SetRotate (90); 
      break; 
     case 7: 
      matrix.SetRotate (-90); 
      matrix.PostScale (-1, 1); 
      break; 
     case 8: 
      matrix.SetRotate (-90); 
      break; 
     default: 
      return bitmap; 
     } 

     try { 
      Bitmap oriented = Bitmap.CreateBitmap (bitmap, 0, 0, bitmap.Width, bitmap.Height, matrix, true); 
      bitmap.Recycle(); 
      return oriented; 
     } catch (OutOfMemoryError e) { 
      e.PrintStackTrace(); 
      return bitmap; 
     } catch (System.Exception e) { 
      System.Diagnostics.Debug.WriteLine (e.Message); 
      return bitmap; 
     } 
    } 

如果有人解决了我的问题,请告诉我。

回答

1

我不确定我是否想念它,但感觉矩阵没有被分配给任何图像?所以你对矩阵所做的任何改变都是你永远看不到的。

我绕到实施这一方式是:

Matrix mtx = new Matrix(); 
    ExifInterface exif = new ExifInterface(fileName); 
    string orientation = exif.GetAttribute(ExifInterface.TagOrientation); 

    switch (orientation) 
    { 
     case "6": // portrait 
      mtx.PreRotate(90); 
      resizedBitmap = Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, mtx, false); 
      mtx.Dispose(); 
      mtx = null; 
      break; 
     case "1": // landscape 
      break; 
     case "8": // Selfie ORIENTATION_ROTATE_270 - might need to flip horizontally too... 
      mtx.PreRotate(270); 
      resizedBitmap = Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, mtx, false); 
      mtx.Dispose(); 
      mtx = null; 
      break; 
    } 

这是.preRotate被分配到Bitmap.CreateBitmap()的矩阵,那么你返回此位大小。 我希望这有助于:)

+0

感谢您的回复。我已经尝试过,但它不起作用。我也观察到我的问题只是从摄像头捕获的图像。当我厌倦了其他图像时,它工作正常。 – Amrut

相关问题