我正在研究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;
}
但问题是我的图像没有被压缩。我无法上传大小= 2MB的图像,我想上传大小至少30 MB的图像。另外我观察到calculateInSampleSize总是返回16,因为inSampleSize是默认值。
如果我的代码中存在任何问题,请与我们联系。
答案 0 :(得分:0)
这似乎是一种非常复杂和复杂的做法。这是一个更简洁的示例,可以帮助您调整图像大小:
CREATE FUNCTION array_distinct(
anyarray, -- input array
boolean DEFAULT false -- flag to ignore nulls
) RETURNS anyarray AS $f$
SELECT array_agg(DISTINCT x)
FROM unnest($1) t(x)
WHERE CASE WHEN $2 THEN x IS NOT NULL ELSE true END;
$f$ LANGUAGE SQL IMMUTABLE;
关于您看到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;
}
}
的原因,我的猜测是您的图片的高度或宽度小于1920(InSampleSize = 16
),因为您使用的是60 * 2 * 16
在while循环中,对该方的更大检查失败,因此,您永远不会进入while主体。
此外,如果您希望创建较小的图像,将它们压缩为Jpeg比使用png更好。