25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 11 KiB

4 년 전
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. [![Build Status](https://travis-ci.org/terikon/cordova-plugin-photo-library.svg?branch=master)](https://travis-ci.org/terikon/cordova-plugin-photo-library)
  2. That's how it looks and performs in real app:
  3. [![](https://img.youtube.com/vi/qHnnRsZ7klE/0.jpg)](https://www.youtube.com/watch?v=qHnnRsZ7klE)
  4. Demo projects (runnable online):
  5. - [For jQuery](https://github.com/terikon/photo-library-demo-jquery)
  6. - [For Ionic 2](https://github.com/terikon/photo-library-demo-ionic2)
  7. - [Vanilla JS with PhotoSwipe](https://github.com/terikon/photo-library-demo-photoswipe)
  8. Displays photo library on cordova's HTML page, by URL. Gets thumbnail of arbitrary sizes, works on multiple platforms, and is fast.
  9. - Displays photo gallery as web page, and not as boring native screen which you cannot modify. This brings back control over your app to you.
  10. For example, you can use [PhotoSwipe](https://github.com/dimsemenov/photoswipe) library to present photos.
  11. - Provides custom schema to access thumbnails: cdvphotolibrary://thumbnail?fileid=xxx&width=128&height=128&quality=0.5 .
  12. - Works on Android, iOS and browser (cordova serve).
  13. - Fast - uses browser cache.
  14. - Can save photos (jpg, png, animated gifs) and videos to specified album on device.
  15. - Handles permissions.
  16. - Handles images [EXIF rotation hell](http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/).
  17. - On iOS, written in Swift and not Objective-C.
  18. **Co-maintainer needed**
  19. Currently Android code is pretty stable, iOS has few stability [issues](https://github.com/terikon/cordova-plugin-photo-library/issues).
  20. **Co-maintainer with iOS/Swift knowlege is needed, please [contact](https://github.com/viskin)**.
  21. Contributions are welcome.
  22. Please add only features that can be supported on both Android and iOS.
  23. Please write tests for your contribution.
  24. # Install
  25. cordova plugin add cordova-plugin-photo-library --variable PHOTO_LIBRARY_USAGE_DESCRIPTION="To choose photos" --save
  26. # Usage
  27. Add cdvphotolibrary protocol to Content-Security-Policy, like this:
  28. ```
  29. <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: cdvphotolibrary:">
  30. ```
  31. For remarks about angular/ionic usage, see below.
  32. ## Displaying photos
  33. ```js
  34. cordova.plugins.photoLibrary.getLibrary(
  35. function (result) {
  36. var library = result.library;
  37. // Here we have the library as array
  38. library.forEach(function(libraryItem) {
  39. console.log(libraryItem.id); // ID of the photo
  40. console.log(libraryItem.photoURL); // Cross-platform access to photo
  41. console.log(libraryItem.thumbnailURL);// Cross-platform access to thumbnail
  42. console.log(libraryItem.fileName);
  43. console.log(libraryItem.width);
  44. console.log(libraryItem.height);
  45. console.log(libraryItem.creationDate);
  46. console.log(libraryItem.latitude);
  47. console.log(libraryItem.longitude);
  48. console.log(libraryItem.albumIds); // array of ids of appropriate AlbumItem, only of includeAlbumsData was used
  49. });
  50. },
  51. function (err) {
  52. console.log('Error occured');
  53. },
  54. { // optional options
  55. thumbnailWidth: 512,
  56. thumbnailHeight: 384,
  57. quality: 0.8,
  58. includeAlbumData: false // default
  59. }
  60. );
  61. ```
  62. This method is fast, as thumbails will be generated on demand.
  63. ## Getting albums
  64. ```js
  65. cordova.plugins.photoLibrary.getAlbums(
  66. function (albums) {
  67. albums.forEach(function(album) {
  68. console.log(album.id);
  69. console.log(album.title);
  70. });
  71. },
  72. function (err) { }
  73. );
  74. ```
  75. ## Saving photos and videos
  76. ``` js
  77. var url = 'file:///...'; // file or remote URL. url can also be dataURL, but giving it a file path is much faster
  78. var album = 'MyAppName';
  79. cordova.plugins.photoLibrary.saveImage(url, album, function (libraryItem) {}, function (err) {});
  80. ```
  81. ```js
  82. // iOS quirks: video provided cannot be .webm . Use .mov or .mp4 .
  83. cordova.plugins.photoLibrary.saveVideo(url, album, function () {}, function (err) {});
  84. ```
  85. saveImage and saveVideo both need write permission to be granted by requestAuthorization.
  86. ## Permissions
  87. The library handles tricky parts of aquiring permissions to photo library.
  88. If any of methods fail because lack of permissions, error string will be returned that begins with 'Permission'. So, to process on aquiring permissions, do the following:
  89. ```js
  90. cordova.plugins.photoLibrary.getLibrary(
  91. function ({library}) { },
  92. function (err) {
  93. if (err.startsWith('Permission')) {
  94. // call requestAuthorization, and retry
  95. }
  96. // Handle error - it's not permission-related
  97. }
  98. );
  99. ```
  100. requestAuthorization is cross-platform method, that works in following way:
  101. - On android, will ask user to allow access to storage
  102. - On ios, on first call will open permission prompt. If user denies it subsequent calls will open setting page of your app, where user should enable access to Photos.
  103. ```js
  104. cordova.plugins.photoLibrary.requestAuthorization(
  105. function () {
  106. // User gave us permission to his library, retry reading it!
  107. },
  108. function (err) {
  109. // User denied the access
  110. }, // if options not provided, defaults to {read: true}.
  111. {
  112. read: true,
  113. write: true
  114. }
  115. );
  116. ```
  117. Read permission is added for your app by the plugin automatically. To make writing possible, add following to your config.xml:
  118. ```xml
  119. <platform name="android">
  120. <config-file target="AndroidManifest.xml" parent="/*">
  121. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  122. </config-file>
  123. </platform>
  124. ```
  125. ## Chunked output
  126. ```js
  127. cordova.plugins.photoLibrary.getLibrary(
  128. function (result) {
  129. var library = result.library;
  130. var isLastChunk = result.isLastChunk;
  131. },
  132. function (err) { },
  133. {
  134. itemsInChunk: 100, // Loading large library takes time, so output can be chunked so that result callback will be called on
  135. chunkTimeSec: 0.5, // each X items, or after Y secons passes. You can start displaying photos immediately.
  136. useOriginalFileNames: false, // default, true will be much slower on iOS
  137. }
  138. );
  139. ```
  140. ## In addition you can ask thumbnail or full image for each photo separately, as cross-platform url or as blob
  141. ```js
  142. // Use this method to get url. It's better to use it and not directly access cdvphotolibrary://, as it will also work on browser.
  143. cordova.plugins.photoLibrary.getThumbnailURL(
  144. libraryItem, // or libraryItem.id
  145. function (thumbnailURL) {
  146. image.src = thumbnailURL;
  147. },
  148. function (err) {
  149. console.log('Error occured');
  150. },
  151. { // optional options
  152. thumbnailWidth: 512,
  153. thumbnailHeight: 384,
  154. quality: 0.8
  155. });
  156. ```
  157. ```js
  158. cordova.plugins.photoLibrary.getPhotoURL(
  159. libraryItem, // or libraryItem.id
  160. function (photoURL) {
  161. image.src = photoURL;
  162. },
  163. function (err) {
  164. console.log('Error occured');
  165. });
  166. ```
  167. ```js
  168. // This method is slower as it does base64
  169. cordova.plugins.photoLibrary.getThumbnail(
  170. libraryItem, // or libraryItem.id
  171. function (thumbnailBlob) {
  172. },
  173. function (err) {
  174. console.log('Error occured');
  175. },
  176. { // optional options
  177. thumbnailWidth: 512,
  178. thumbnailHeight: 384,
  179. quality: 0.8
  180. });
  181. ```
  182. ```js
  183. // This method is slower as it does base64
  184. cordova.plugins.photoLibrary.getPhoto(
  185. libraryItem, // or libraryItem.id
  186. function (fullPhotoBlob) {
  187. },
  188. function (err) {
  189. console.log('Error occured');
  190. });
  191. ```
  192. # ionic / angular
  193. It's best to use from [ionic-native](https://ionicframework.com/docs/v2/native/photo-library). The the docs.
  194. As mentioned [here](https://github.com/terikon/cordova-plugin-photo-library/issues/15) by dnmd, cdvphotolibrary urls should bypass sanitization to work.
  195. In angular2, do following:
  196. Define Pipe that will tell to bypass trusted urls. cdvphotolibrary urls should be trusted:
  197. ```js
  198. // cdvphotolibrary.pipe.ts
  199. import { Pipe, PipeTransform } from '@angular/core';
  200. import { DomSanitizer } from '@angular/platform-browser';
  201. @Pipe({name: 'cdvphotolibrary'})
  202. export class CDVPhotoLibraryPipe implements PipeTransform {
  203. constructor(private sanitizer: DomSanitizer) {}
  204. transform(url: string) {
  205. return url.startsWith('cdvphotolibrary://') ? this.sanitizer.bypassSecurityTrustUrl(url) : url;
  206. }
  207. }
  208. ```
  209. Register the pipe in your module:
  210. ```js
  211. import { CDVPhotoLibraryPipe } from './cdvphotolibrary.pipe.ts';
  212. @NgModule({
  213. declarations: [
  214. CDVPhotoLibraryPipe,
  215. // ...
  216. ],
  217. })
  218. ```
  219. Then in your component, use cdvphotolibrary urls applying the cdvphotolibrary pipe:
  220. ```js
  221. @Component({
  222. selector: 'app',
  223. template: '<img [src]="url | cdvphotolibrary">'
  224. })
  225. export class AppComponent {
  226. public url: string = 'placeholder.jpg';
  227. constructor() {
  228. // fetch thumbnail URL's
  229. this.url = libraryItem.thumbnailURL;
  230. }
  231. }
  232. ```
  233. If you use angular1, you need to add cdvphotolibrary to whitelist:
  234. ```js
  235. var app = angular
  236. .module('myApp', [])
  237. .config([
  238. '$compileProvider',
  239. function ($compileProvider) {
  240. $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|cdvphotolibrary):/);
  241. //Angular 1.2 and above has two sanitization methods, one for links (aHrefSanitizationWhitelist) and
  242. //one for images (imgSrcSanitizationWhitelist). Versions prior to 1.2 use $compileProvider.urlSanitizationWhitelist(...)
  243. }
  244. ]);
  245. ```
  246. # TypeScript
  247. TypeScript definitions are provided in [PhotoLibrary.d.ts](https://github.com/terikon/cordova-plugin-photo-library/blob/master/PhotoLibrary.d.ts)
  248. # Tests
  249. The library includes tests in [tests](https://github.com/terikon/cordova-plugin-photo-library/tree/master/tests) folder. All tests are in
  250. [tests.js](https://github.com/terikon/cordova-plugin-photo-library/blob/master/tests/tests.js) file.
  251. # Running tests
  252. ## Travis
  253. tcc.db file is located at $HOME/Library/Developer/CoreSimulator/Devices/$DEVICEID/data/Library/TCC/TCC.db
  254. ## Helper app
  255. To run tests, use [special photo-library-tester](https://github.com/terikon/photo-library-tester).
  256. It's always useful to run these tests before submitting changes, for each platform (android, ios, browser).
  257. # TODO
  258. - [#38](https://github.com/terikon/cordova-plugin-photo-library/issues/38) browser platform: saveImage and saveVideo should download file.
  259. - Improve documentation.
  260. - Provide cancellation mechanism for long-running operations, like getLibrary.
  261. - CI.
  262. # Optional enchancements
  263. - iOS: it seems regex causes slowdown with dataURL, and (possibly) uses too much memory - check how to do regex on iOS in better way.
  264. - Browser platform: Separate to multiple files.
  265. - Android: caching mechanism like [this one](https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html) can be helpful.
  266. - Implement save protocol with HTTP POST, so no base64 transformation will be needed for saving.
  267. - EXIF rotation hell is not handled on browser platform.
  268. - Pre-fetching data to file-based cache on app start can improve responsiveness. Just this caching should occur as low-priority thread. Cache can be updated
  269. by system photo libraries events.
  270. # References
  271. Parts are based on
  272. - https://github.com/subitolabs/cordova-gallery-api
  273. - https://github.com/SuryaL/cordova-gallery-api
  274. - https://github.com/ryouaki/Cordova-Plugin-Photos
  275. - https://github.com/devgeeks/Canvas2ImagePlugin