Xamarin形式Android压缩后的图像方向更改
问题描述:
我正在写一个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;
}
}
如果有人解决了我的问题,请告诉我。
答
我不确定我是否想念它,但感觉矩阵没有被分配给任何图像?所以你对矩阵所做的任何改变都是你永远看不到的。
我绕到实施这一方式是:
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()的矩阵,那么你返回此位大小。 我希望这有助于:)
感谢您的回复。我已经尝试过,但它不起作用。我也观察到我的问题只是从摄像头捕获的图像。当我厌倦了其他图像时,它工作正常。 – Amrut