UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

461 lines • 18 kB
import { Font } from '../ui/styling/font'; import { Trace } from '../trace'; // Types. import { path as fsPath, knownFolders } from '../file-system'; import { isFileOrResourcePath, RESOURCE_PREFIX, SYSTEM_PREFIX } from '../utils'; import { getScaledDimensions } from './image-source-common'; export { isFileOrResourcePath }; let http; function ensureHttp() { if (!http) { http = require('../http'); } } export class ImageSource { get height() { if (this.ios) { return this.ios.size.height; } return NaN; } get width() { if (this.ios) { return this.ios.size.width; } return NaN; } get rotationAngle() { return NaN; } set rotationAngle(_value) { // compatibility with Android } constructor(nativeSource) { if (nativeSource) { this.setNativeSource(nativeSource); } } static fromAsset(asset) { return new Promise((resolve, reject) => { asset.getImageAsync((image, err) => { if (image) { resolve(new ImageSource(image)); } else { reject(err); } }); }); } static fromUrl(url) { ensureHttp(); return http.getImage(url); } static iosSystemScaleFor(scale) { switch (scale) { case 'small': return 1 /* UIImageSymbolScale.Small */; case 'medium': return 2 /* UIImageSymbolScale.Medium */; case 'large': return 3 /* UIImageSymbolScale.Large */; default: return -1 /* UIImageSymbolScale.Default */; } } static fromSystemImageSync(name, instance) { if (instance?.iosSymbolScale) { const image = ImageSource.systemImageWithConfig(name, instance); return image ? new ImageSource(image) : null; } else { const image = UIImage.systemImageNamed(name); return image ? new ImageSource(image) : null; } } static fromSystemImage(name, instance) { return new Promise((resolve, reject) => { try { let image; if (instance?.iosSymbolScale) { image = ImageSource.systemImageWithConfig(name, instance); } else { image = UIImage.systemImageNamed(name); } if (image) { resolve(new ImageSource(image)); } else { reject(new Error(`Failed to load system icon with name: ${name}`)); } } catch (ex) { reject(ex); } }); } static systemImageWithConfig(name, instance) { const fontSize = instance.style.fontSize; const fontWeight = instance.style.fontWeight; return UIImage.systemImageNamedWithConfiguration(name, fontSize ? UIImageSymbolConfiguration.configurationWithPointSizeWeightScale(fontSize, fontWeight === 'bold' ? 7 /* UIImageSymbolWeight.Bold */ : 4 /* UIImageSymbolWeight.Regular */, ImageSource.iosSystemScaleFor(instance.iosSymbolScale)) : UIImageSymbolConfiguration.configurationWithScale(ImageSource.iosSystemScaleFor(instance.iosSymbolScale))); } static fromResourceSync(name) { const nativeSource = UIImage.tns_safeImageNamed(name) || UIImage.tns_safeImageNamed(`${name}.jpg`); return nativeSource ? new ImageSource(nativeSource) : null; } static fromResource(name) { return new Promise((resolve, reject) => { try { UIImage.tns_safeDecodeImageNamedCompletion(name, (image) => { if (image) { resolve(new ImageSource(image)); } else { UIImage.tns_safeDecodeImageNamedCompletion(`${name}.jpg`, (img) => { if (img) { resolve(new ImageSource(img)); } }); } }); } catch (ex) { reject(ex); } }); } static fromFileSync(path) { const uiImage = UIImage.imageWithContentsOfFile(getFileName(path)); return uiImage ? new ImageSource(uiImage) : null; } static fromFile(path) { return new Promise((resolve, reject) => { try { UIImage.tns_decodeImageWidthContentsOfFileCompletion(getFileName(path), (uiImage) => { if (uiImage) { resolve(new ImageSource(uiImage)); } }); } catch (ex) { reject(ex); } }); } static fromFileOrResourceSync(path) { if (!isFileOrResourcePath(path)) { if (Trace.isEnabled()) { Trace.write('Path "' + path + '" is not a valid file or resource.', Trace.categories.Binding, Trace.messageType.error); } return null; } if (path.indexOf(RESOURCE_PREFIX) === 0) { return ImageSource.fromResourceSync(path.slice(RESOURCE_PREFIX.length)); } if (path.indexOf(SYSTEM_PREFIX) === 0) { return ImageSource.fromSystemImageSync(path.slice(SYSTEM_PREFIX.length)); } return ImageSource.fromFileSync(path); } static fromDataSync(data) { const uiImage = UIImage.imageWithData(data); return uiImage ? new ImageSource(uiImage) : null; } static fromData(data) { return new Promise((resolve, reject) => { try { UIImage.tns_decodeImageWithDataCompletion(data, (uiImage) => { if (uiImage) { resolve(new ImageSource(uiImage)); } }); } catch (ex) { reject(ex); } }); } static fromBase64Sync(source) { let uiImage; if (typeof source === 'string') { const data = NSData.alloc().initWithBase64EncodedStringOptions(source, 1 /* NSDataBase64DecodingOptions.IgnoreUnknownCharacters */); uiImage = UIImage.imageWithData(data); } return uiImage ? new ImageSource(uiImage) : null; } static fromBase64(source) { return new Promise((resolve, reject) => { try { const data = NSData.alloc().initWithBase64EncodedStringOptions(source, 1 /* NSDataBase64DecodingOptions.IgnoreUnknownCharacters */); const main_queue = dispatch_get_current_queue(); const background_queue = dispatch_get_global_queue(21 /* qos_class_t.QOS_CLASS_DEFAULT */, 0); dispatch_async(background_queue, () => { const uiImage = UIImage.imageWithData(data); dispatch_async(main_queue, () => { resolve(new ImageSource(uiImage)); }); }); } catch (ex) { reject(ex); } }); } static fromFontIconCodeSync(source, font, color) { font = font || Font.default; // TODO: Consider making 36 font size as default for optimal look on TabView and ActionBar const attributes = { [NSFontAttributeName]: font.getUIFont(UIFont.systemFontOfSize(UIFont.labelFontSize)), }; if (color) { attributes[NSForegroundColorAttributeName] = color.ios; } const attributedString = NSAttributedString.alloc().initWithStringAttributes(source, attributes); UIGraphicsBeginImageContextWithOptions(attributedString.size(), false, 0.0); attributedString.drawAtPoint(CGPointMake(0, 0)); const iconImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return iconImage ? new ImageSource(iconImage) : null; } fromAsset(asset) { console.log('fromAsset() is deprecated. Use ImageSource.fromAsset() instead.'); return ImageSource.fromAsset(asset).then((imgSource) => { this.setNativeSource(imgSource.ios); return this; }); } loadFromResource(name) { console.log('loadFromResource() is deprecated. Use ImageSource.fromResourceSync() instead.'); const imgSource = ImageSource.fromResourceSync(name); this.ios = imgSource ? imgSource.ios : null; return !!this.ios; } fromResource(name) { console.log('fromResource() is deprecated. Use ImageSource.fromResource() instead.'); return ImageSource.fromResource(name).then((imgSource) => { this.ios = imgSource.ios; return !!this.ios; }); } loadFromFile(path) { console.log('loadFromFile() is deprecated. Use ImageSource.fromFileSync() instead.'); const imgSource = ImageSource.fromFileSync(path); this.ios = imgSource ? imgSource.ios : null; return !!this.ios; } fromFile(path) { console.log('fromFile() is deprecated. Use ImageSource.fromFile() instead.'); return ImageSource.fromFile(path).then((imgSource) => { this.ios = imgSource.ios; return !!this.ios; }); } loadFromData(data) { console.log('loadFromData() is deprecated. Use ImageSource.fromDataSync() instead.'); const imgSource = ImageSource.fromDataSync(data); this.ios = imgSource ? imgSource.ios : null; return !!this.ios; } fromData(data) { console.log('fromData() is deprecated. Use ImageSource.fromData() instead.'); return ImageSource.fromData(data).then((imgSource) => { this.ios = imgSource.ios; return !!this.ios; }); } loadFromBase64(source) { console.log('loadFromBase64() is deprecated. Use ImageSource.fromBase64Sync() instead.'); const imgSource = ImageSource.fromBase64Sync(source); this.ios = imgSource ? imgSource.ios : null; return !!this.ios; } fromBase64(source) { console.log('fromBase64() is deprecated. Use ImageSource.fromBase64() instead.'); return ImageSource.fromBase64(source).then((imgSource) => { this.ios = imgSource.ios; return !!this.ios; }); } loadFromFontIconCode(source, font, color) { console.log('loadFromFontIconCode() is deprecated. Use ImageSource.fromFontIconCodeSync() instead.'); const imgSource = ImageSource.fromFontIconCodeSync(source, font, color); this.ios = imgSource ? imgSource.ios : null; return !!this.ios; } getNativeSource() { return this.ios; } setNativeSource(source) { if (!source) { this.ios = null; } else if (source instanceof UIImage) { this.ios = source; } else { if (Trace.isEnabled()) { Trace.write('The method setNativeSource() expects UIImage instance.', Trace.categories.Binding, Trace.messageType.error); } } } saveToFile(path, format, quality) { if (!this.ios) { return false; } if (quality) { quality = (quality - 0) / (100 - 0); // Normalize quality on a scale of 0 to 1 } const data = getImageData(this.ios, format, quality); if (data) { return NSFileManager.defaultManager.createFileAtPathContentsAttributes(path, data, null); } return false; } saveToFileAsync(path, format, quality) { return new Promise((resolve, reject) => { if (!this.ios) { reject(false); } let isSuccess = false; try { if (quality) { quality = (quality - 0) / (100 - 0); // Normalize quality on a scale of 0 to 1 } const main_queue = dispatch_get_current_queue(); const background_queue = dispatch_get_global_queue(21 /* qos_class_t.QOS_CLASS_DEFAULT */, 0); dispatch_async(background_queue, () => { const data = getImageData(this.ios, format, quality); if (data) { isSuccess = NSFileManager.defaultManager.createFileAtPathContentsAttributes(path, data, null); } dispatch_async(main_queue, () => { resolve(isSuccess); }); }); } catch (ex) { reject(ex); } }); } toBase64String(format, quality) { let res = null; if (!this.ios) { return res; } if (quality) { quality = (quality - 0) / (100 - 0); // Normalize quality on a scale of 0 to 1 } const data = getImageData(this.ios, format, quality); if (data) { res = data.base64Encoding(); } return res; } toBase64StringAsync(format, quality) { return new Promise((resolve, reject) => { if (!this.ios) { reject(null); } let result = null; try { if (quality) { quality = (quality - 0) / (100 - 0); // Normalize quality on a scale of 0 to 1 } const main_queue = dispatch_get_current_queue(); const background_queue = dispatch_get_global_queue(21 /* qos_class_t.QOS_CLASS_DEFAULT */, 0); dispatch_async(background_queue, () => { const data = getImageData(this.ios, format, quality); if (data) { result = data.base64Encoding(); } dispatch_async(main_queue, () => { resolve(result); }); }); } catch (ex) { reject(ex); } }); } resize(maxSize, options) { const size = this.ios.size; const dim = getScaledDimensions(size.width, size.height, maxSize); const newSize = CGSizeMake(dim.width, dim.height); UIGraphicsBeginImageContextWithOptions(newSize, options?.opaque ?? false, this.ios.scale); this.ios.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height)); const resizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return new ImageSource(resizedImage); } resizeAsync(maxSize, options) { return new Promise((resolve, reject) => { if (!this.ios) { reject(null); } const main_queue = dispatch_get_current_queue(); const background_queue = dispatch_get_global_queue(21 /* qos_class_t.QOS_CLASS_DEFAULT */, 0); dispatch_async(background_queue, () => { const size = this.ios.size; const dim = getScaledDimensions(size.width, size.height, maxSize); const newSize = CGSizeMake(dim.width, dim.height); UIGraphicsBeginImageContextWithOptions(newSize, options?.opaque ?? false, this.ios.scale); this.ios.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height)); const resizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); dispatch_async(main_queue, () => { resolve(new ImageSource(resizedImage)); }); }); }); } } function getFileName(path) { let fileName = typeof path === 'string' ? path.trim() : ''; if (fileName.indexOf('~/') === 0) { fileName = fsPath.join(knownFolders.currentApp().path, fileName.replace('~/', '')); } return fileName; } function getImageData(instance, format, quality = 0.9) { return NativeScriptUtils.getImageDataFormatQuality(instance, format, quality); } export function fromAsset(asset) { console.log('fromAsset() is deprecated. Use ImageSource.fromAsset() instead.'); return ImageSource.fromAsset(asset); } export function fromResource(name) { console.log('fromResource() is deprecated. Use ImageSource.fromResourceSync() instead.'); return ImageSource.fromResourceSync(name); } export function fromFile(path) { console.log('fromFile() is deprecated. Use ImageSource.fromFileSync() instead.'); return ImageSource.fromFileSync(path); } export function fromData(data) { console.log('fromData() is deprecated. Use ImageSource.fromDataSync() instead.'); return ImageSource.fromDataSync(data); } export function fromFontIconCode(source, font, color) { console.log('fromFontIconCode() is deprecated. Use ImageSource.fromFontIconCodeSync() instead.'); return ImageSource.fromFontIconCodeSync(source, font, color); } export function fromBase64(source) { console.log('fromBase64() is deprecated. Use ImageSource.fromBase64Sync() instead.'); return ImageSource.fromBase64Sync(source); } export function fromNativeSource(nativeSource) { console.log('fromNativeSource() is deprecated. Use ImageSource constructor instead.'); return new ImageSource(nativeSource); } export function fromUrl(url) { console.log('fromUrl() is deprecated. Use ImageSource.fromUrl() instead.'); return ImageSource.fromUrl(url); } export function fromFileOrResource(path) { console.log('fromFileOrResource() is deprecated. Use ImageSource.fromFileOrResourceSync() instead.'); return ImageSource.fromFileOrResourceSync(path); } //# sourceMappingURL=index.ios.js.map