防止 FireMonkey 缩小照片
Preventing FireMonkey from shrinking photo
问题:
我在 FireMonkey (XE 10.1 Berlin) 中有一个移动应用程序需要拍照。问题是 FireMonkey 似乎将我的图片重新调整为更小,至少在 Android 上是这样。
我不仅看到这种情况发生在我自己的应用程序中,而且还出现在 FireMonkey 附带的 PhotoEditor 演示应用程序中。
当我在 FireMonkey 外用相机拍照时,图像大小约为 6-7 Mb,大小为 5184 x 2916 像素。
当我使用我的应用程序或使用 PhotoEditor 演示应用程序拍照时,图像大小介于 140 和 180 kB 之间,大小为 365 x 648 像素。
这发生在 Android;我手边没有 Mac,所以我现在无法在 iPad 或 iPhone 上进行测试。
到目前为止我发现了什么:
我在代码中设置了断点以找出发生这种情况的位置。当 OnDidFinishTaking
事件处理程序被调用时,它接收到的图像已经缩小了。
事件是从 FMX.MediaLibrary.Android.pas
中的 procedure TImageManagerAndroid.DidReceiveBitmap(const Sender: TObject; const M: TMessage);
调用的。
在这种情况下,我看到了这一行:
Photo := TBitmap.CreateFromFile(ImagePath);
ImagePath
指的是设备上的.jpg文件,已经缩小了。
进一步查看调用堆栈,我看到了对
的调用
procedure TFMXNativeActivityListener.onReceiveImagePath(ARequestCode: Integer; AFileName: JString);
此程序存在于 FMX.Platform.Android.pas
。
查看此过程的声明时,我看到它后面跟着关键字 cdecl
,这可能暗示此方法是从本机 Android 代码调用的。
我也看过 this tutorial。这里使用了 IFMXCameraService.TakePhoto
过程。值得注意的是,PhotoEditor 演示中使用的是而非!
使用它可能是一个选项,因为它需要一个包含 RequiredResolution
字段的参数的记录。但是,我更愿意使用类似于 PhotoEditor 演示的方法。
问题:
如何防止 FireMonkey 缩小我的照片?
我发现 FireMonkey 对于使用 TTakeCustomPhotoAction
拍摄的照片有默认的最大宽度和高度。如果图像不适合最大尺寸,则图片会缩小。收缩因子总是2的幂,所以FireMonkey似乎一直在将图像减半直到适合。
TTakeCustomPhotoAction
(TTakePhotoFromCameraAction
的直接基础 class)定义了两个属性,MaxWidth
和 MaxHeight
。出于某种原因,它们都默认为 1024。
通过将默认值设置为更高的值,例如 8192,您可以防止收缩:
actTakePhotoFromCameraAction1.MaxWidth := Max(8192, actTakePhotoFromCameraAction1.MaxWidth);
actTakePhotoFromCameraAction1.MaxHeight := Max(8192, actTakePhotoFromCameraAction1.MaxHeight);
这些默认属性的类型为 Cardinal
,这意味着它们的最大值为 4.294.967.295 (0xFFFFFFFF) - 它们是 8 字节的无符号值。
问题:
我在 FireMonkey (XE 10.1 Berlin) 中有一个移动应用程序需要拍照。问题是 FireMonkey 似乎将我的图片重新调整为更小,至少在 Android 上是这样。 我不仅看到这种情况发生在我自己的应用程序中,而且还出现在 FireMonkey 附带的 PhotoEditor 演示应用程序中。
当我在 FireMonkey 外用相机拍照时,图像大小约为 6-7 Mb,大小为 5184 x 2916 像素。
当我使用我的应用程序或使用 PhotoEditor 演示应用程序拍照时,图像大小介于 140 和 180 kB 之间,大小为 365 x 648 像素。
这发生在 Android;我手边没有 Mac,所以我现在无法在 iPad 或 iPhone 上进行测试。
到目前为止我发现了什么:
我在代码中设置了断点以找出发生这种情况的位置。当 OnDidFinishTaking
事件处理程序被调用时,它接收到的图像已经缩小了。
事件是从 FMX.MediaLibrary.Android.pas
中的 procedure TImageManagerAndroid.DidReceiveBitmap(const Sender: TObject; const M: TMessage);
调用的。
在这种情况下,我看到了这一行:
Photo := TBitmap.CreateFromFile(ImagePath);
ImagePath
指的是设备上的.jpg文件,已经缩小了。
进一步查看调用堆栈,我看到了对
的调用procedure TFMXNativeActivityListener.onReceiveImagePath(ARequestCode: Integer; AFileName: JString);
此程序存在于 FMX.Platform.Android.pas
。
查看此过程的声明时,我看到它后面跟着关键字 cdecl
,这可能暗示此方法是从本机 Android 代码调用的。
我也看过 this tutorial。这里使用了 IFMXCameraService.TakePhoto
过程。值得注意的是,PhotoEditor 演示中使用的是而非!
使用它可能是一个选项,因为它需要一个包含 RequiredResolution
字段的参数的记录。但是,我更愿意使用类似于 PhotoEditor 演示的方法。
问题:
如何防止 FireMonkey 缩小我的照片?
我发现 FireMonkey 对于使用 TTakeCustomPhotoAction
拍摄的照片有默认的最大宽度和高度。如果图像不适合最大尺寸,则图片会缩小。收缩因子总是2的幂,所以FireMonkey似乎一直在将图像减半直到适合。
TTakeCustomPhotoAction
(TTakePhotoFromCameraAction
的直接基础 class)定义了两个属性,MaxWidth
和 MaxHeight
。出于某种原因,它们都默认为 1024。
通过将默认值设置为更高的值,例如 8192,您可以防止收缩:
actTakePhotoFromCameraAction1.MaxWidth := Max(8192, actTakePhotoFromCameraAction1.MaxWidth);
actTakePhotoFromCameraAction1.MaxHeight := Max(8192, actTakePhotoFromCameraAction1.MaxHeight);
这些默认属性的类型为 Cardinal
,这意味着它们的最大值为 4.294.967.295 (0xFFFFFFFF) - 它们是 8 字节的无符号值。