RequestContentEditingInput completionHandler 不 运行
RequestContentEditingInput completionHandler do not run
我有一个应用程序,我需要从 phone 中选择图像并按照用户选择它们的顺序显示它们
(我需要按选择顺序排列的 img,而不是 "most recent edited" 这就是我不使用 UIImagePickerController 的原因)
为此,我有一个页面显示最新的 50 张图片,并且可以加载更多图片。
我正在使用下面的代码获取图像路径和方向。
我的问题:CompletionHandler(在 RequestContentEditingInput 中)只会 运行 17 次...
我可以看到每个图像都调用了 RequestContentEditingInput(在此 phone 138 次)
我尝试等待,但没有任何反应。
当我的图片少于 17 张时,代码会按预期工作...
我试图在 CompletionHandler 代码中实现一个 SemaphoreSlim 锁来控制我一次只能处理 10 个图像,但最终结果是相同的或根本没有处理图像。
UpdateInfo:似乎是所有未处理的LivePhotos。
有人知道这里发生了什么吗?
有修复的想法吗?
还有其他方法可以获得所有图像路径和方向吗?
或者让用户从 phone 中选择图像并获取用户选择它们的顺序的完全不同的解决方案?
public class GalleryHelper : IGalleryHelper
{
private List<(string, string, string)> _retval;
private nint _numberofImg = 0;
private nint _currentImg = 0;
public List<(string, string, string)> GetAllImgFromGallery()
{
_retval = new List<(string, string, string)>();
_currentImg = 0;
GetAllImg();
return _retval;
}
private void GetAllImg()
{
var fetchOptions = new PHFetchOptions();
PHFetchResult allPhotos = PHAsset.FetchAssets(PHAssetMediaType.Image, fetchOptions);
_numberofImg = allPhotos.Count;
Debug.WriteLine("Total img no + " + _numberofImg);
for (nint i = 0; i < allPhotos.Count; i++)
{
Debug.WriteLine("Starting " + i);
(allPhotos[i] as PHAsset).RequestContentEditingInput(new PHContentEditingInputRequestOptions(), CompletionHandler);
}
}
private void CompletionHandler(PHContentEditingInput contentEditingInput, NSDictionary requestStatusInfo)
{
Debug.WriteLine("Starting CompletionHandler " + (1 + _currentImg));
var path = contentEditingInput.FullSizeImageUrl.Path;
if (path != null)
{
var orientation = contentEditingInput.FullSizeImageOrientation;
switch (orientation)
{
case CIImageOrientation.TopLeft:
//Standard position
_retval.Add((path, null, "0"));
break;
case CIImageOrientation.LeftBottom:
//Rotate 90 degrees clockwise
_retval.Add((path, null, "-90"));
break;
case CIImageOrientation.RightTop:
//Rotate 90 degrees counterclockwise
_retval.Add((path, null, "90"));
break;
case CIImageOrientation.BottomRight:
//Rotate 180 degrees
_retval.Add((path, null, "180"));
break;
case CIImageOrientation.BottomLeft:
//Mirror image rotated 180 degrees
_retval.Add((path, null, "180"));
break;
case CIImageOrientation.TopRight:
//Mirror image
_retval.Add((path, null, "0"));
break;
case CIImageOrientation.LeftTop:
//Mirror image rotate 90 degrees clockwise
_retval.Add((path, null, "-90"));
break;
case CIImageOrientation.RightBottom:
//Mirror image rotate 90 degrees counterclockwise.
_retval.Add((path, null, "90"));
break;
default:
_retval.Add((path, null, "0"));
break;
}
}
_currentImg++;
Debug.WriteLine("Images done " + _currentImg);
MessagingCenter.Send((App)Xamarin.Forms.Application.Current, "ImagesReady", _retval);
}
}
从我的调试输出粘贴到 运行:
[0:] Total img no + 138
[0:] Starting 0
[0:] Starting 1
(...)
[0:] Starting 137
[0:] Starting CompletionHandler 1
[0:] Images done 1
[0:] Starting CompletionHandler 2
[0:] Images done 2
[0:] Starting CompletionHandler 3
[0:] Images done 3
(...)
[0:] Starting CompletionHandler 15
[0:] Images done 15
[0:] Starting CompletionHandler 16
[0:] Images done 16
[0:] Starting CompletionHandler 17
[0:] Images done 17
Thread started: #17
Thread finished: #15
The thread 0xf has exited with code 0 (0x0).
Thread finished: #3
如果以后有人遇到同样的问题。
使用 PHImageManager.DefaultManager.RequestImageData() 而不是 PHAsset.RequestContentEditingInput(),因为如果您要求它处理大量图像,它不会崩溃。
我会这样做:
var fetchOptions = new PHFetchOptions();
PHFetchResult allPhotos = PHAsset.FetchAssets(PHAssetMediaType.Image, fetchOptions);
_numberofImg = allPhotos.Count;
Debug.WriteLine("Total img no + " + _numberofImg);
await Task.Yield();
await Task.Run(() => ImgProcess(allPhotos));
return true;
private void ImgProcess(PHFetchResult allPhotos)
{
//await Task.Run(() =>
//{
for (nint i = 0; i < allPhotos.Count; i++)
{
Debug.WriteLine("Starting " + i);
var phasset = allPhotos[i] as PHAsset;
var options = new PHImageRequestOptions()
{
Synchronous = true,
NetworkAccessAllowed = false,
DeliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat
};
PHImageManager.DefaultManager.RequestImageData(phasset, options, ComplManager);
}
//});
//return;
}
即使当图像数量超过 300 张时此解决方案仍然存在问题...
我有一个应用程序,我需要从 phone 中选择图像并按照用户选择它们的顺序显示它们 (我需要按选择顺序排列的 img,而不是 "most recent edited" 这就是我不使用 UIImagePickerController 的原因)
为此,我有一个页面显示最新的 50 张图片,并且可以加载更多图片。
我正在使用下面的代码获取图像路径和方向。
我的问题:CompletionHandler(在 RequestContentEditingInput 中)只会 运行 17 次... 我可以看到每个图像都调用了 RequestContentEditingInput(在此 phone 138 次)
我尝试等待,但没有任何反应。
当我的图片少于 17 张时,代码会按预期工作...
我试图在 CompletionHandler 代码中实现一个 SemaphoreSlim 锁来控制我一次只能处理 10 个图像,但最终结果是相同的或根本没有处理图像。
UpdateInfo:似乎是所有未处理的LivePhotos。
有人知道这里发生了什么吗?
有修复的想法吗?
还有其他方法可以获得所有图像路径和方向吗?
或者让用户从 phone 中选择图像并获取用户选择它们的顺序的完全不同的解决方案?
public class GalleryHelper : IGalleryHelper
{
private List<(string, string, string)> _retval;
private nint _numberofImg = 0;
private nint _currentImg = 0;
public List<(string, string, string)> GetAllImgFromGallery()
{
_retval = new List<(string, string, string)>();
_currentImg = 0;
GetAllImg();
return _retval;
}
private void GetAllImg()
{
var fetchOptions = new PHFetchOptions();
PHFetchResult allPhotos = PHAsset.FetchAssets(PHAssetMediaType.Image, fetchOptions);
_numberofImg = allPhotos.Count;
Debug.WriteLine("Total img no + " + _numberofImg);
for (nint i = 0; i < allPhotos.Count; i++)
{
Debug.WriteLine("Starting " + i);
(allPhotos[i] as PHAsset).RequestContentEditingInput(new PHContentEditingInputRequestOptions(), CompletionHandler);
}
}
private void CompletionHandler(PHContentEditingInput contentEditingInput, NSDictionary requestStatusInfo)
{
Debug.WriteLine("Starting CompletionHandler " + (1 + _currentImg));
var path = contentEditingInput.FullSizeImageUrl.Path;
if (path != null)
{
var orientation = contentEditingInput.FullSizeImageOrientation;
switch (orientation)
{
case CIImageOrientation.TopLeft:
//Standard position
_retval.Add((path, null, "0"));
break;
case CIImageOrientation.LeftBottom:
//Rotate 90 degrees clockwise
_retval.Add((path, null, "-90"));
break;
case CIImageOrientation.RightTop:
//Rotate 90 degrees counterclockwise
_retval.Add((path, null, "90"));
break;
case CIImageOrientation.BottomRight:
//Rotate 180 degrees
_retval.Add((path, null, "180"));
break;
case CIImageOrientation.BottomLeft:
//Mirror image rotated 180 degrees
_retval.Add((path, null, "180"));
break;
case CIImageOrientation.TopRight:
//Mirror image
_retval.Add((path, null, "0"));
break;
case CIImageOrientation.LeftTop:
//Mirror image rotate 90 degrees clockwise
_retval.Add((path, null, "-90"));
break;
case CIImageOrientation.RightBottom:
//Mirror image rotate 90 degrees counterclockwise.
_retval.Add((path, null, "90"));
break;
default:
_retval.Add((path, null, "0"));
break;
}
}
_currentImg++;
Debug.WriteLine("Images done " + _currentImg);
MessagingCenter.Send((App)Xamarin.Forms.Application.Current, "ImagesReady", _retval);
}
}
从我的调试输出粘贴到 运行:
[0:] Total img no + 138
[0:] Starting 0
[0:] Starting 1
(...)
[0:] Starting 137
[0:] Starting CompletionHandler 1
[0:] Images done 1
[0:] Starting CompletionHandler 2
[0:] Images done 2
[0:] Starting CompletionHandler 3
[0:] Images done 3
(...)
[0:] Starting CompletionHandler 15
[0:] Images done 15
[0:] Starting CompletionHandler 16
[0:] Images done 16
[0:] Starting CompletionHandler 17
[0:] Images done 17
Thread started: #17
Thread finished: #15
The thread 0xf has exited with code 0 (0x0).
Thread finished: #3
如果以后有人遇到同样的问题。 使用 PHImageManager.DefaultManager.RequestImageData() 而不是 PHAsset.RequestContentEditingInput(),因为如果您要求它处理大量图像,它不会崩溃。
我会这样做:
var fetchOptions = new PHFetchOptions();
PHFetchResult allPhotos = PHAsset.FetchAssets(PHAssetMediaType.Image, fetchOptions);
_numberofImg = allPhotos.Count;
Debug.WriteLine("Total img no + " + _numberofImg);
await Task.Yield();
await Task.Run(() => ImgProcess(allPhotos));
return true;
private void ImgProcess(PHFetchResult allPhotos)
{
//await Task.Run(() =>
//{
for (nint i = 0; i < allPhotos.Count; i++)
{
Debug.WriteLine("Starting " + i);
var phasset = allPhotos[i] as PHAsset;
var options = new PHImageRequestOptions()
{
Synchronous = true,
NetworkAccessAllowed = false,
DeliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat
};
PHImageManager.DefaultManager.RequestImageData(phasset, options, ComplManager);
}
//});
//return;
}
即使当图像数量超过 300 张时此解决方案仍然存在问题...