-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Enable sending Original Quality images with metadata preservation #6145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable sending Original Quality images with metadata preservation #6145
Conversation
- Add ImageQualitySettingStore for per-thread quality preferences - Simple toggle: default vs original - Stores per-thread setting in KeyValueStore - resolvedQualityLevel() falls back to system default - Add ImageQualityLevel.original enum case - Max file size: 100 MiB (vs 6 MiB for high quality) - Starting tier: .seven (highest quality) - Localized as 'Original' This provides the foundation for opt-in per-thread original quality images with full metadata preservation.
SignalAttachment changes: - Add preserveMetadata flag to control metadata stripping - Defer image conversion to preparedForOutput(qualityLevel:) - Early-return original files when qualityLevel is .original - Implement removingImageMetadata() for when conversion is needed - Update isValidOutputOriginal to accept input image formats PhotoLibrary changes: - Always use PHAssetResourceManager to get original file bytes - Preserves all metadata (EXIF, GPS, etc.) in exported data - Metadata stripping now happens in preparedForOutput() based on quality This allows sending original HEIC/PNG/JPEG files with full metadata when Original quality is selected, while still supporting metadata removal for other quality levels.
- Add ImageQualitySettingsViewController - Simple toggle: Default vs Original Quality - Warning text about metadata/location preservation - Push navigation from conversation settings - Integrate into ConversationSettingsViewController - New 'Image Quality' row shows current setting - Displays 'Default' or 'Original Quality' - Add localization strings for settings and quality options - Update Xcode project to include new view controller Users can now opt-in to Original quality per conversation, which will preserve all image metadata including GPS location data.
AttachmentApprovalViewController: - Add 2-button quality selector (Standard | Original) - Read per-thread setting and default to Original when enabled - Show Original option in multi-recipient flows with subtitle 'Applies where enabled' - Set preserveMetadata flag when Original is selected - Accessibility support for quality control (VoiceOver adjustable) MediaItemViewController: - Fix preview to use attachmentStream.decryptedImage() - Ensures 'Save from preview' preserves EXIF metadata Flow integration: - Pass thread context to AttachmentApprovalViewController where available - Update SendMediaNavigationController, ConversationViewController, CameraFirstCaptureSendFlow, and SharingThreadPickerViewController The approval UI now respects per-thread Original quality settings and defaults the quality selector appropriately.
- Implement per-thread quality processing in AttachmentMultisend - Read each destination thread's quality setting - Process attachments once at the highest quality level needed - Original quality recipients get original files with metadata - Other recipients get downsampled versions (high/standard) This respects per-thread Original quality settings even when sending to multiple recipients with different quality preferences, while minimizing redundant processing by preparing attachments at the max quality needed.
547cbd9 to
33970ac
Compare
|
Hi, thanks for your interest in contributing. This is something we've considered in the past, and there are things we want to improve in this space, but unfortunately I don't think this is the direction we'd take. (Due to the surface area and product/UX implications, this type of complex feature is also generally difficult for us to integrate from a public contribution.) Metadata preservation is something we intentionally don't support, and we believe it's important that that be a uniform decision. With regards to image quality, we already expose a "Sent Media Quality" setting in Settings > Data Usage and on a per-send basis. We understand that regardless of the Sent Media Quality setting, media sending over Signal on iOS often has subpar performance. Fortunately, we have significant improvements to media quality and performance under active development, as it's something we care a lot about and friction we ourselves experience all the time. Thanks again for your interest in contributing, and as always for being a Signal user. |
|
Hey thanks for your reply. I understand, this is a large change with many UX implications 😄
Can you explain what you mean by uniform decision? This option could also be implemented similar to disappearing messages (shared setting for all users in a thread) or as a global per-sender setting, but both of these are less privacy-preserving options. Photo metadata (plus full image quality) is nice for photo archiving and to utilize the full features of photo organization apps. And it is frustrating that when chatting with trusted contacts (close friends / family), metadata is always removed if sending with the nice photo picker UI. This can already be worked around by sending photos as attachments, but this UX is terrible; it would be nice if users could enable sending exact byte-for-byte images to select chats. In any case, this PR demonstrates that this can be achieved with a simple and clean implementation. I hope you will reconsider this as part of your photo sharing improvements. |
First time contributor checklist
Contributor checklist
Tested sending and receiving from the above devices, plus the following flows:
Description
This PR adds an opt-in, per-thread setting that allows users to send images in their original format with full metadata (EXIF, GPS, etc.) preserved. When enabled for a conversation, images are sent as original files (HEIC, PNG, JPEG) up to 100 MiB without compression or metadata stripping.
User-Facing Changes
Thread Settings
Users can now enable "Original Quality" for individual conversations through a new Image Quality settings screen accessible from the conversation settings menu.
The setting is a simple toggle:
A warning message informs users that Original Quality preserves location data and other metadata that could inadvertently reveal where photos were taken.
Attachment Approval Screen
When sending images, users see a quality selector that respects the per-thread setting:
Technical Implementation
Storage Layer
ImageQualitySettingStore: Per-thread key-value storage for quality preferences (default vs original)ImageQualityLevel.original: New enum case with 100 MiB max file sizeAttachment Pipeline
SignalAttachment.preserveMetadata: Flag to control metadata strippingpreparedForOutput(qualityLevel:): Defers image conversion; returns original files when quality is.originalPhotoLibrary: Always exports original file bytes viaPHAssetResourceManager; metadata stripping happens inpreparedForOutput()based on quality levelUI Integration
ImageQualitySettingsViewController: New per-thread settings screen with toggle switchAttachmentApprovalViewController: 2-button quality selector with per-thread defaultMediaItemViewController: Fixed preview to useattachmentStream.decryptedImage()so "Save from preview" preserves EXIF metadataMulti-Recipient Support
AttachmentMultisend: Processes attachments once at the highest quality needed across all recipientsTesting Notes
Migration
No database migration required. The setting is additive and defaults to system behavior for all existing conversations.