Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 43 additions & 101 deletions src/Essentials/src/MediaPicker/MediaPicker.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ partial class MediaPickerImplementation : IMediaPicker
public bool IsCaptureSupported
=> Application.Context?.PackageManager?.HasSystemFeature(PackageManager.FeatureCameraAny) ?? false;

static async Task RotateImageInPlace(string filePath, MediaPickerOptions options)
{
using var inputStream = File.OpenRead(filePath);
var fileName = System.IO.Path.GetFileName(filePath);
using var rotatedStream = await ImageProcessor.RotateImageAsync(inputStream, fileName);
rotatedStream.Position = 0;
inputStream.Dispose(); // explicit close before delete
try
{ File.Delete(filePath); }
catch { }
using var outputStream = File.Create(filePath);
await rotatedStream.CopyToAsync(outputStream);
}

internal static bool IsPhotoPickerAvailable
=> PickVisualMedia.InvokeIsPhotoPickerAvailable(Platform.AppContext);

Expand Down Expand Up @@ -85,30 +99,10 @@ public async Task<FileResult> CaptureAsync(MediaPickerOptions options, bool phot
if (photo)
{
captureResult = await CapturePhotoAsync(captureIntent);
// Apply rotation if needed for photos
if (captureResult is not null && ImageProcessor.IsRotationNeeded(options))
{
using var inputStream = File.OpenRead(captureResult);
var fileName = System.IO.Path.GetFileName(captureResult);
using var rotatedStream = await ImageProcessor.RotateImageAsync(inputStream, fileName);

var rotatedPath = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(captureResult),
System.IO.Path.GetFileNameWithoutExtension(captureResult) + "_rotated" + System.IO.Path.GetExtension(captureResult));

using var outputStream = File.Create(rotatedPath);
rotatedStream.Position = 0;
await rotatedStream.CopyToAsync(outputStream);

// Use the rotated image and delete the original
try
{
File.Delete(captureResult);
}
catch { }
captureResult = rotatedPath;
}

// Apply rotation if needed for photos
if (captureResult is not null && ImageProcessor.IsRotationNeeded(options))
await RotateImageInPlace(captureResult, options);

// Apply compression/resizing if needed for photos
if (captureResult is not null && ImageProcessor.IsProcessingNeeded(options?.MaximumWidth, options?.MaximumHeight, options?.CompressionQuality ?? 100))
{
Expand Down Expand Up @@ -161,30 +155,15 @@ void OnResult(Intent intent)
{
// Apply rotation if needed
if (ImageProcessor.IsRotationNeeded(options))
{
using var inputStream = File.OpenRead(path);
var fileName = System.IO.Path.GetFileName(path);
using var rotatedStream = await ImageProcessor.RotateImageAsync(inputStream, fileName);

var rotatedPath = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(path),
System.IO.Path.GetFileNameWithoutExtension(path) + "_rotated" + System.IO.Path.GetExtension(path));

using var outputStream = File.Create(rotatedPath);
rotatedStream.Position = 0;
await rotatedStream.CopyToAsync(outputStream);

// Use the rotated image
path = rotatedPath;
}
await RotateImageInPlace(path, options);

// Apply compression/resizing if needed
if (ImageProcessor.IsProcessingNeeded(options?.MaximumWidth, options?.MaximumHeight, options?.CompressionQuality ?? 100))
{
path = await CompressImageIfNeeded(path, options);
}
}

return new FileResult(path);
}

Expand Down Expand Up @@ -215,22 +194,7 @@ async Task<FileResult> PickUsingPhotoPicker(MediaPickerOptions options, bool pho
{
// Apply rotation if needed
if (ImageProcessor.IsRotationNeeded(options))
{
using var inputStream = File.OpenRead(path);
var fileName = System.IO.Path.GetFileName(path);
using var rotatedStream = await ImageProcessor.RotateImageAsync(inputStream, fileName);

var rotatedPath = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(path),
System.IO.Path.GetFileNameWithoutExtension(path) + "_rotated" + System.IO.Path.GetExtension(path));

using var outputStream = File.Create(rotatedPath);
rotatedStream.Position = 0;
await rotatedStream.CopyToAsync(outputStream);

// Use the rotated image
path = rotatedPath;
}
await RotateImageInPlace(path, options);

// Apply compression/resizing if needed
if (ImageProcessor.IsProcessingNeeded(options?.MaximumWidth, options?.MaximumHeight, options?.CompressionQuality ?? 100))
Expand Down Expand Up @@ -281,27 +245,12 @@ async Task<List<FileResult>> PickMultipleUsingPhotoPicker(MediaPickerOptions opt
if (!uri?.Equals(AndroidUri.Empty) ?? false)
{
var path = FileSystemUtils.EnsurePhysicalPath(uri);

if (photo)
{
// Apply rotation if needed
if (ImageProcessor.IsRotationNeeded(options))
{
using var inputStream = File.OpenRead(path);
var fileName = System.IO.Path.GetFileName(path);
using var rotatedStream = await ImageProcessor.RotateImageAsync(inputStream, fileName);

var rotatedPath = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(path),
System.IO.Path.GetFileNameWithoutExtension(path) + "_rotated" + System.IO.Path.GetExtension(path));

using var outputStream = File.Create(rotatedPath);
rotatedStream.Position = 0;
await rotatedStream.CopyToAsync(outputStream);

// Use the rotated image
path = rotatedPath;
}
await RotateImageInPlace(path, options);

// Apply compression/resizing if needed
if (ImageProcessor.IsProcessingNeeded(options?.MaximumWidth, options?.MaximumHeight, options?.CompressionQuality ?? 100))
Expand Down Expand Up @@ -368,21 +317,29 @@ static async Task<string> CompressImageIfNeeded(string imagePath, MediaPickerOpt

if (processedStream != null)
{
// Determine output extension based on processed data and original filename
// Determine the correct output extension based on the processed format
processedStream.Position = 0;
var outputExtension = ImageProcessor.DetermineOutputExtension(processedStream, options?.CompressionQuality ?? 100, inputFileName);
var processedFileName = System.IO.Path.GetFileNameWithoutExtension(imagePath) + "_processed" + outputExtension;
var processedPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(imagePath), processedFileName);
var originalExtension = System.IO.Path.GetExtension(imagePath);

// Write processed image to file
using var outputStream = File.Create(processedPath);
processedStream.Position = 0;
await processedStream.CopyToAsync(outputStream);
// If format changed (e.g., PNG -> JPEG), use new extension
string outputPath = imagePath;
if (!string.Equals(outputExtension, originalExtension, StringComparison.OrdinalIgnoreCase))
{
outputPath = System.IO.Path.ChangeExtension(imagePath, outputExtension);
}

// Delete original file
// Delete original file first
try
{ originalFile.Delete(); }
catch { }
return processedPath;

// Write processed image to output path with correct extension
using var outputStream = File.Create(outputPath);
processedStream.Position = 0;
await processedStream.CopyToAsync(outputStream);

return outputPath;
}

// If ImageProcessor returns null (e.g., on .NET Standard), ImageProcessor.IsProcessingNeeded would have returned false,
Expand Down Expand Up @@ -481,32 +438,17 @@ void OnResult(Intent resultIntent)
foreach (var path in tempResultList)
{
string processedPath = path;

// Apply rotation if needed
if (ImageProcessor.IsRotationNeeded(options))
{
using var inputStream = File.OpenRead(processedPath);
var fileName = System.IO.Path.GetFileName(processedPath);
using var rotatedStream = await ImageProcessor.RotateImageAsync(inputStream, fileName);

var rotatedPath = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(processedPath),
System.IO.Path.GetFileNameWithoutExtension(processedPath) + "_rotated" + System.IO.Path.GetExtension(processedPath));

using var outputStream = File.Create(rotatedPath);
rotatedStream.Position = 0;
await rotatedStream.CopyToAsync(outputStream);

// Use the rotated image
processedPath = rotatedPath;
}
await RotateImageInPlace(processedPath, options);

// Apply compression/resizing if needed
if (ImageProcessor.IsProcessingNeeded(options?.MaximumWidth, options?.MaximumHeight, options?.CompressionQuality ?? 100))
{
processedPath = await CompressImageIfNeeded(processedPath, options);
}

resultList.Add(new FileResult(processedPath));
}
}
Expand Down
Loading