1

Via UIImagePickerController, is there a way to tell if the image the user chose from their library is a screenshot? Also, is there a timestamp associated with screenshots? I've read Get Exif data from UIImage - UIImagePickerController, but do screenshots in particular have this data?

Community
  • 1
  • 1
tcd
  • 1,585
  • 2
  • 17
  • 38
  • 4
    I think a common way of achieving this is to see if the image dimensions are the same as those of the device. Not fool proof but should catch most. – Paul.s Mar 08 '14 at 17:10
  • That's true... hopefully there's a "no-doubt" way! – tcd Mar 08 '14 at 17:11
  • 1
    possible duplicate of [Can I detect if an imported ALAsset photo was taken via screenshot?](http://stackoverflow.com/questions/12953669/can-i-detect-if-an-imported-alasset-photo-was-taken-via-screenshot) – Daij-Djan Mar 08 '14 at 17:18
  • Seems to be a duplicate, missed that post, thanks! – tcd Mar 08 '14 at 17:26

3 Answers3

5

Images taken as screenshots dont have EXIF metadata. The reason behind that is EXIF metadata is mostly added by Camera and contains information such as Aperture, Shutter Speed, Flash, etc.

You can also check if images dimensions matches screen resolution.

Finally neither of above rules, are full proof. One can always have images with EXIF metadata(like Orientation) and images of same resolution as mobile screen, however the chances are low for that.

For a backend processor, one can also do template matching for icons like battery symbol, network strength, etc.

saurabheights
  • 3,967
  • 2
  • 31
  • 50
1

Yes YOU CAN. I'm doing it.

First of all, clarify that I am working with NativeScript in Javascript language, but the code is easily understandable for any iOS developer.

First you need to get the PHAsset from the result of your UIImagePickerController, you can easily do it based on answers like this: How to retrieve PHAsset from UIImagePickerController

Then you must obtain its Exif data, check the UserComment property, and if it corresponds to Screenshot, it will effectively be a screenshot.

PHCachingImageManager.defaultManager().requestImageDataForAssetOptionsResultHandler( asset, this.requestImageDataForAssetOption, (data,uti,orientation,info) => {
    if( !data ) return resolve(false);
    
    let options = NSDictionary.dictionaryWithObjectForKey(kCFBooleanFalse,'kCGImageSourceShouldCache')
    let imgSrc = CGImageSourceCreateWithData(data, options)
    let metadata = CGImageSourceCopyPropertiesAtIndex(imgSrc, 0, options)
    var Exif = metadata.objectForKey('{Exif}')
    if( !Exif ) return resolve(false);

    let userComment = String( Exif.valueForKey('UserComment') )

    if( userComment == 'Screenshot' ) return resolve(true);
    resolve(false)
})

You can also easily get the date the screenshot was taken from the PHAsset con su propiedad creationDate.

Macarthurval
  • 178
  • 11
-2

In order to explain this code, well.

The iPhone and iPad are having retina display which provides a "somehow" unique resolution on saved image. When your user-uploaded image contains following resolution, it is mostly a screenshot.

The following resolution combines are the same as App Store Connect's one, and the codes here do the same as AAPL. More resolutions? Find it out yourself, bro.

The success rate is nearly 100% in my 2w+ photo libraries which I recently decided to clean it up.

So magical? Yes. Photos are taken in different resolutions. Anyway, it is not possible to tell a cropped screenshot without using AI or EXIF data.

    if width == 312  && heigh == 390  { /* Apple Watch */ }
    if width == 640  && heigh == 960  { /* iPhone 3 + 4 */ }
    if heigh == 640  && width == 960  { /* iPhone 3 + 4 land  */ }
    if width == 640  && heigh == 1136 { /* iPhone 5 */ }
    if heigh == 640  && width == 1136 { /* iPhone 5 land */ }
    if width == 750  && heigh == 1334 { /* iPhone 6/7/8 */ }
    if heigh == 750  && width == 1334 { /* iPhone 6/7/8 land */ }
    if width == 1242 && heigh == 2208 { /* iPhone + */ }
    if heigh == 1242 && width == 2208 { /* iPhone + land */ }
    if width == 1125 && heigh == 2436 { /* iPad X  */ }
    if heigh == 1125 && width == 2436 { /* iPhone X land */ }
    if width == 1536 && heigh == 2048 { /* iPhone Air + mini */ }
    if heigh == 1536 && width == 2048 { /* iPhone Air + mini land  */ }
    if width == 2048 && heigh == 2732 { /* iPhone Pro 12.9 */ }
    if heigh == 2048 && width == 2732 { /* iPhone Pro 12.9 land */ }
Lane
  • 61
  • 1
  • 2
  • 1
    Please add some elaborating information so that anybody can understand the meaning of your code :) – Markus Jan 19 '20 at 01:12
  • This does not provide an answer to the question. Please [edit] your answer to ensure that it improves upon other answers already present in this question. – hongsy Jan 19 '20 at 03:38