Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
Merge latest in
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesmontemagno committed Oct 11, 2019
2 parents 2979397 + 7d26df5 commit 7c541c5
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 157 deletions.
2 changes: 2 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
patreon: mergeconflictfm
custom: https://www.buymeacoffee.com/jamesmontemagno
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,11 @@ It is highly recommended that you use a custom Application that are outlined in

## Android Misc Setup

By adding these permissions [Google Play will automatically filter out devices](http://developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions-features) without specific hardware. You can get around this by adding the following to your AssemblyInfo.cs file in your Android project:
By default, the library adds `android.hardware.camera` and `android.hardware.camera.autofocus` to your apps manifest as optional features. It is your responsbility to check whether your device supports the hardware before using it. If instead you'd like [Google Play to filter out devices](http://developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions-features) without the required hardware, add the following to your AssemblyInfo.cs file in your Android project:

```
[assembly: UsesFeature("android.hardware.camera", Required = false)]
[assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)]
[assembly: UsesFeature("android.hardware.camera", Required = true)]
[assembly: UsesFeature("android.hardware.camera.autofocus", Required = true)]
```


Expand Down
10 changes: 8 additions & 2 deletions src/Media.Plugin/Android/IntentExtraExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ public static void UseFrontCamera(this Intent intent)

// Android API 25 and up
intent.PutExtra(extraFrontPost25, 1);
intent.PutExtra(extraUserFront, true);

var isIntentNeeded = intent.GetBooleanExtra(extraUserFront, false);
if (isIntentNeeded)
intent.PutExtra(extraUserFront, true);
}

public static void UseBackCamera(this Intent intent)
Expand All @@ -27,7 +30,10 @@ public static void UseBackCamera(this Intent intent)

// Android API 25 and up
intent.PutExtra(extraBackPost25, 1);
intent.PutExtra(extraUserFront, false);

var isIntentNeeded = intent.GetBooleanExtra(extraUserFront, false);
if (isIntentNeeded)
intent.PutExtra(extraUserFront, false);
}
}
}
3 changes: 3 additions & 0 deletions src/Media.Plugin/Android/MediaImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ bool IsValidExif(ExifInterface exif)

var medias = await TakeMediasAsync("image/*", Intent.ActionPick, new StorePickerMediaOptions { MultiPicker = true }, token);

if (medias == null)
return null;

if (options == null)
options = new PickMediaOptions();

Expand Down
148 changes: 35 additions & 113 deletions src/Media.Plugin/iOS/ECLImagePickerViewController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading.Tasks;
using CoreGraphics;
using Plugin.Media.Abstractions;
using System.Linq;

namespace Plugin.Media
{
Expand Down Expand Up @@ -139,30 +140,13 @@ public static ELCImagePickerViewController Create(StoreCameraMediaOptions option
_options = options ?? new StoreCameraMediaOptions();
}

void SelectedAssets(List<ALAsset> assets)
{
var results = new List<MediaFile>();
foreach (var asset in assets)
{
var obj = asset.AssetType;
if (obj == default(ALAssetType))
continue;

var rep = asset.DefaultRepresentation;
if (rep != null)
{
var mediaFile = GetPictureMediaFile(asset);
if (mediaFile != null)
{
results.Add(mediaFile);
}
}
}

_TaskCompletionSource.TrySetResult(results);
void SelectedMediaFiles(List<MediaFile> mediaFiles)
{
_TaskCompletionSource.TrySetResult(mediaFiles);
}

private MediaFile GetPictureMediaFile(ALAsset asset)
private MediaFile GetPictureMediaFile(ALAsset asset, long index = 0)
{
var rep = asset.DefaultRepresentation;
if (rep == null)
Expand All @@ -172,91 +156,19 @@ private MediaFile GetPictureMediaFile(ALAsset asset)

var path = MediaPickerDelegate.GetOutputPath(MediaImplementation.TypeImage,
_options.Directory ?? "temp",
_options.Name);
_options.Name, index);

var image = new UIImage(cgImage, 1.0f, (UIImageOrientation)rep.Orientation);
cgImage?.Dispose();
cgImage = null;
rep?.Dispose();
rep = null;

var percent = 1.0f;
if (_options.PhotoSize != PhotoSize.Full)
{
try
{
switch (_options.PhotoSize)
{
case PhotoSize.Large:
percent = .75f;
break;
case PhotoSize.Medium:
percent = .5f;
break;
case PhotoSize.Small:
percent = .25f;
break;
case PhotoSize.Custom:
percent = (float)_options.CustomPhotoSize / 100f;
break;
}

if (_options.PhotoSize == PhotoSize.MaxWidthHeight && _options.MaxWidthHeight.HasValue)
{
var max = Math.Max(image.CGImage.Width, image.CGImage.Height);
if (max > _options.MaxWidthHeight.Value)
{
percent = (float)_options.MaxWidthHeight.Value / (float)max;
}
}

if (percent < 1.0f)
{
//begin resizing image
image = image.ResizeImageWithAspectRatio(percent);
}

}
catch (Exception ex)
{
Console.WriteLine($"Unable to compress image: {ex}");
}
}


NSDictionary meta = null;
try
{
//meta = PhotoLibraryAccess.GetPhotoLibraryMetadata(asset.AssetUrl);

//meta = info[UIImagePickerController.MediaMetadata] as NSDictionary;
if (meta != null && meta.ContainsKey(ImageIO.CGImageProperties.Orientation))
{
var newMeta = new NSMutableDictionary();
newMeta.SetValuesForKeysWithDictionary(meta);
var newTiffDict = new NSMutableDictionary();
newTiffDict.SetValuesForKeysWithDictionary(meta[ImageIO.CGImageProperties.TIFFDictionary] as NSDictionary);
newTiffDict.SetValueForKey(meta[ImageIO.CGImageProperties.Orientation], ImageIO.CGImageProperties.TIFFOrientation);
newMeta[ImageIO.CGImageProperties.TIFFDictionary] = newTiffDict;

meta = newMeta;
}
var location = _options.Location;
if (meta != null && location != null)
{
meta = MediaPickerDelegate.SetGpsLocation(meta, location);
}
}
catch (Exception ex)
{
Console.WriteLine($"Unable to get metadata: {ex}");
}

//iOS quality is 0.0-1.0
var quality = (_options.CompressionQuality / 100f);
var savedImage = false;
if (meta != null)
savedImage = MediaPickerDelegate.SaveImageWithMetadata(image, quality, meta, path);

if (!savedImage)
image.AsJPEG(quality).Save(path, true);
image.AsJPEG().Save(path, true);

image?.Dispose();
image = null;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Default);

string aPath = null;
//try to get the album path's url
Expand Down Expand Up @@ -577,8 +489,11 @@ private void AssetSelected(NSIndexPath targetIndexPath, bool selected)
if (ImmediateReturn)
{
var asset = AssetForIndexPath(targetIndexPath);
var obj = new List<ALAsset> { asset };
Parent.SelectedAssets(obj);
var mediaFile = Parent?.GetPictureMediaFile(asset);
asset?.Dispose();
asset = null;
var selectedMediaFile = new List<MediaFile>() { mediaFile };
Parent?.SelectedMediaFiles(selectedMediaFile);
}
}

Expand Down Expand Up @@ -621,18 +536,25 @@ private void PhotoEnumerator(ALAsset result, nint index, ref bool stop)

private void DoneClicked(object sender = null, EventArgs e = null)
{
var selected = new List<ALAsset>();
var parent = Parent;
var selectedItemsIndex = CollectionView.GetIndexPathsForSelectedItems();
var selectedItemsCount = selectedItemsIndex.Length;
var selectedMediaFiles = new MediaFile[selectedItemsCount];

foreach (var selectedIndexPath in CollectionView.GetIndexPathsForSelectedItems())
Parallel.For(0, selectedItemsCount, selectedIndex =>
{
selected.Add(AssetForIndexPath(selectedIndexPath));
}
var alAsset = AssetForIndexPath(selectedItemsIndex[selectedIndex]);
var mediaFile = parent?.GetPictureMediaFile(alAsset, selectedIndex);
if (mediaFile != null)
{
selectedMediaFiles[selectedIndex] = mediaFile;
}

var parent = Parent;
if (parent != null)
{
parent.SelectedAssets(selected);
}
alAsset?.Dispose();
alAsset = null;
});

parent?.SelectedMediaFiles(selectedMediaFiles.ToList());
}

class ELCAssetCell : UICollectionViewCell
Expand Down
103 changes: 98 additions & 5 deletions src/Media.Plugin/iOS/MediaImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ public class MediaImplementation : IMedia
/// </summary>
public static UIStatusBarStyle StatusBarStyle { get; set; }



///<inheritdoc/>
public Task<bool> Initialize() => Task.FromResult(true);
///<inheritdoc/>
public Task<bool> Initialize() => Task.FromResult(true);

/// <summary>
/// Implementation
Expand Down Expand Up @@ -346,7 +345,7 @@ private static MediaPickerController SetupController(MediaPickerDelegate mpDeleg
var ndelegate = new MediaPickerDelegate(viewController, sourceType, options, token);
var od = Interlocked.CompareExchange(ref pickerDelegate, ndelegate, null);
if (od != null)
throw new InvalidOperationException("Only one operation can be active at at time");
throw new InvalidOperationException("Only one operation can be active at a time");

var picker = ELCImagePickerViewController.Create(options, pickerOptions);

Expand Down Expand Up @@ -379,10 +378,104 @@ private static MediaPickerController SetupController(MediaPickerDelegate mpDeleg
return Task.FromResult(new List<MediaFile>());
}

var files = t.Result;
Parallel.ForEach(files, mediaFile =>
{
ResizeAndCompressImage(options, mediaFile);
});

return t;
}).Unwrap();
}

private static void ResizeAndCompressImage(StoreCameraMediaOptions options, MediaFile mediaFile)
{
var image = UIImage.FromFile(mediaFile.Path);
var percent = 1.0f;
if (options.PhotoSize != PhotoSize.Full)
{
try
{
switch (options.PhotoSize)
{
case PhotoSize.Large:
percent = .75f;
break;
case PhotoSize.Medium:
percent = .5f;
break;
case PhotoSize.Small:
percent = .25f;
break;
case PhotoSize.Custom:
percent = (float)options.CustomPhotoSize / 100f;
break;
}

if (options.PhotoSize == PhotoSize.MaxWidthHeight && options.MaxWidthHeight.HasValue)
{
var max = Math.Max(image.Size.Width, image.Size.Height);
if (max > options.MaxWidthHeight.Value)
{
percent = (float)options.MaxWidthHeight.Value / (float)max;
}
}

if (percent < 1.0f)
{
//begin resizing image
image = image.ResizeImageWithAspectRatio(percent);
}

NSDictionary meta = null;
try
{
//meta = PhotoLibraryAccess.GetPhotoLibraryMetadata(asset.AssetUrl);

//meta = info[UIImagePickerController.MediaMetadata] as NSDictionary;
if (meta != null && meta.ContainsKey(ImageIO.CGImageProperties.Orientation))
{
var newMeta = new NSMutableDictionary();
newMeta.SetValuesForKeysWithDictionary(meta);
var newTiffDict = new NSMutableDictionary();
newTiffDict.SetValuesForKeysWithDictionary(meta[ImageIO.CGImageProperties.TIFFDictionary] as NSDictionary);
newTiffDict.SetValueForKey(meta[ImageIO.CGImageProperties.Orientation], ImageIO.CGImageProperties.TIFFOrientation);
newMeta[ImageIO.CGImageProperties.TIFFDictionary] = newTiffDict;

meta = newMeta;
}
var location = options.Location;
if (meta != null && location != null)
{
meta = MediaPickerDelegate.SetGpsLocation(meta, location);
}
}
catch (Exception ex)
{
Console.WriteLine($"Unable to get metadata: {ex}");
}

//iOS quality is 0.0-1.0
var quality = (options.CompressionQuality / 100f);
var savedImage = false;
if (meta != null)
savedImage = MediaPickerDelegate.SaveImageWithMetadata(image, quality, meta, mediaFile.Path);

if (!savedImage)
image.AsJPEG(quality).Save(mediaFile.Path, true);

image?.Dispose();
image = null;

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
}
catch (Exception ex)
{
Console.WriteLine($"Unable to compress image: {ex}");
}
}
}

private void Dismiss(UIPopoverController popover, UIViewController picker)
{
if (popover != null)
Expand All @@ -399,7 +492,7 @@ private void Dismiss(UIPopoverController popover, UIViewController picker)
{

}

GC.Collect(GC.MaxGeneration, GCCollectionMode.Default);
Interlocked.Exchange(ref pickerDelegate, null);
}

Expand Down
Loading

0 comments on commit 7c541c5

Please sign in to comment.