FireMonkey使用TTakePhotoFromCameraAction如何控制拍摄图片分辨率?
解决方案(兼容Delphi 10.4.2 Sydney + 安卓/iOS双平台)
一、TTakePhotoFromCameraAction 拍摄分辨率控制说明
Delphi 10.4.2 自带的 TTakePhotoFromCameraAction 没有直接暴露跨平台的分辨率设置参数,要实现拍摄阶段控制输出大小,可选择两种实现路径:
- 路径1:修改原生调用逻辑,适配双平台底层API
安卓端可调用Camera API的
setPictureSize方法指定输出分辨率;iOS端可调整AVCaptureSession的sessionPreset属性为对应画质预设(如AVCaptureSessionPreset1280x720),该方案可在拍摄阶段直接控制输出体积,减少后续性能开销,但需要额外编写平台原生适配代码。 - 路径2:跳过拍摄阶段参数调整,统一对输出图像做后期压缩,同时适配拍照、图库选择场景,实现成本更低,兼容性更稳定。
二、跨平台图像压缩最优方案(同时适配拍照/图库选图场景)
该方案无需修改拍摄、选图的原生逻辑,仅需在获取到图像后统一处理,可直接适配TTakePhotoFromCameraAction和TTakePhotoFromLibraryAction两个组件的OnDidFinishTaking事件。
核心实现代码
- 按目标最长边等比缩放Bitmap
procedure ResizeBitmap(const ABitmap: TBitmap; const MaxEdge: Integer); var NewWidth, NewHeight: Integer; begin if ABitmap = nil then Exit; // 计算等比缩放后的宽高 if ABitmap.Width > ABitmap.Height then begin NewWidth := MaxEdge; NewHeight := Round(ABitmap.Height * MaxEdge / ABitmap.Width); end else begin NewHeight := MaxEdge; NewWidth := Round(ABitmap.Width * MaxEdge / ABitmap.Height); end; ABitmap.Resize(NewWidth, NewHeight); end;
可根据业务需求调整
MaxEdge参数,常规场景设置为1280或1920即可兼顾清晰度和体积。
- 调整压缩质量导出为JPG流
function CompressBitmapToJPG(const ABitmap: TBitmap; const Quality: Integer): TStream; var Jpg: TJPEGImage; begin Result := TMemoryStream.Create; if ABitmap = nil then Exit; Jpg := TJPEGImage.Create; try Jpg.Assign(ABitmap); Jpg.CompressionQuality := Quality; // 取值范围0-100,建议设置为60-80,平衡画质与体积 Jpg.Compress; Jpg.SaveToStream(Result); Result.Position := 0; finally Jpg.Free; end; end;
业务接入方式
- 拍照场景:在
TTakePhotoFromCameraAction的OnDidFinishTaking事件中,先将事件返回的Bitmap传入上述两个方法处理,再赋值给TImage组件 - 图库选图场景:在
TTakePhotoFromLibraryAction的OnDidFinishTaking事件中执行完全相同的处理逻辑即可
三、注意事项
- 权限配置:安卓端需提前申请
CAMERA、READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限;iOS端需在Info.plist中添加NSCameraUsageDescription、NSPhotoLibraryUsageDescription权限描述 - 内存管理:Delphi 10.4.2的FMX.Bitmap在iOS端存在偶发内存泄漏问题,处理完图像后需及时调用
Free释放资源 - 格式适配:如果需要输出PNG格式,替换
TJPEGImage为TPNGImage,调整对应压缩等级参数即可
内容的提问来源于stack exchange,提问作者rhazell
相关产品推荐
相关产品推荐

