mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
chore: format
This commit is contained in:
@@ -3,63 +3,76 @@ import { Observable } from "../data/observable";
|
||||
import { screen as platformScreen } from "../platform";
|
||||
|
||||
export class ImageAssetBase extends Observable implements ImageAssetDefinition {
|
||||
private _options: ImageAssetOptions;
|
||||
private _nativeImage: any;
|
||||
private _options: ImageAssetOptions;
|
||||
private _nativeImage: any;
|
||||
|
||||
ios: PHAsset;
|
||||
android: string;
|
||||
ios: PHAsset;
|
||||
android: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._options = { keepAspectRatio: true, autoScaleFactor: true };
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this._options = { keepAspectRatio: true, autoScaleFactor: true };
|
||||
}
|
||||
|
||||
get options(): ImageAssetOptions {
|
||||
return this._options;
|
||||
}
|
||||
get options(): ImageAssetOptions {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
set options(value: ImageAssetOptions) {
|
||||
this._options = value;
|
||||
}
|
||||
set options(value: ImageAssetOptions) {
|
||||
this._options = value;
|
||||
}
|
||||
|
||||
get nativeImage(): any {
|
||||
return this._nativeImage;
|
||||
}
|
||||
get nativeImage(): any {
|
||||
return this._nativeImage;
|
||||
}
|
||||
|
||||
set nativeImage(value: any) {
|
||||
this._nativeImage = value;
|
||||
}
|
||||
set nativeImage(value: any) {
|
||||
this._nativeImage = value;
|
||||
}
|
||||
|
||||
public getImageAsync(callback: (image: any, error: Error) => void) {
|
||||
//
|
||||
}
|
||||
public getImageAsync(callback: (image: any, error: Error) => void) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
export function getAspectSafeDimensions(sourceWidth, sourceHeight, reqWidth, reqHeight) {
|
||||
let widthCoef = sourceWidth / reqWidth;
|
||||
let heightCoef = sourceHeight / reqHeight;
|
||||
let aspectCoef = Math.min(widthCoef, heightCoef);
|
||||
export function getAspectSafeDimensions(
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
reqWidth,
|
||||
reqHeight
|
||||
) {
|
||||
let widthCoef = sourceWidth / reqWidth;
|
||||
let heightCoef = sourceHeight / reqHeight;
|
||||
let aspectCoef = Math.min(widthCoef, heightCoef);
|
||||
|
||||
return {
|
||||
width: Math.floor(sourceWidth / aspectCoef),
|
||||
height: Math.floor(sourceHeight / aspectCoef)
|
||||
};
|
||||
return {
|
||||
width: Math.floor(sourceWidth / aspectCoef),
|
||||
height: Math.floor(sourceHeight / aspectCoef),
|
||||
};
|
||||
}
|
||||
|
||||
export function getRequestedImageSize(src: { width: number, height: number }, options: ImageAssetOptions): { width: number, height: number } {
|
||||
const screen = platformScreen.mainScreen;
|
||||
export function getRequestedImageSize(
|
||||
src: { width: number; height: number },
|
||||
options: ImageAssetOptions
|
||||
): { width: number; height: number } {
|
||||
const screen = platformScreen.mainScreen;
|
||||
|
||||
let reqWidth = options.width || Math.min(src.width, screen.widthPixels);
|
||||
let reqHeight = options.height || Math.min(src.height, screen.heightPixels);
|
||||
let reqWidth = options.width || Math.min(src.width, screen.widthPixels);
|
||||
let reqHeight = options.height || Math.min(src.height, screen.heightPixels);
|
||||
|
||||
if (options && options.keepAspectRatio) {
|
||||
let safeAspectSize = getAspectSafeDimensions(src.width, src.height, reqWidth, reqHeight);
|
||||
reqWidth = safeAspectSize.width;
|
||||
reqHeight = safeAspectSize.height;
|
||||
}
|
||||
if (options && options.keepAspectRatio) {
|
||||
let safeAspectSize = getAspectSafeDimensions(
|
||||
src.width,
|
||||
src.height,
|
||||
reqWidth,
|
||||
reqHeight
|
||||
);
|
||||
reqWidth = safeAspectSize.width;
|
||||
reqHeight = safeAspectSize.height;
|
||||
}
|
||||
|
||||
return {
|
||||
width: reqWidth,
|
||||
height: reqHeight
|
||||
};
|
||||
return {
|
||||
width: reqWidth,
|
||||
height: reqHeight,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,87 +4,119 @@ import { path as fsPath, knownFolders } from "../file-system";
|
||||
export * from "./image-asset-common";
|
||||
|
||||
export class ImageAsset extends ImageAssetBase {
|
||||
private _android: string; //file name of the image
|
||||
private _android: string; //file name of the image
|
||||
|
||||
constructor(asset: string) {
|
||||
super();
|
||||
let fileName = typeof asset === "string" ? asset.trim() : "";
|
||||
if (fileName.indexOf("~/") === 0) {
|
||||
fileName = fsPath.join(knownFolders.currentApp().path, fileName.replace("~/", ""));
|
||||
}
|
||||
this.android = fileName;
|
||||
}
|
||||
constructor(asset: string) {
|
||||
super();
|
||||
let fileName = typeof asset === "string" ? asset.trim() : "";
|
||||
if (fileName.indexOf("~/") === 0) {
|
||||
fileName = fsPath.join(
|
||||
knownFolders.currentApp().path,
|
||||
fileName.replace("~/", "")
|
||||
);
|
||||
}
|
||||
this.android = fileName;
|
||||
}
|
||||
|
||||
get android(): string {
|
||||
return this._android;
|
||||
}
|
||||
get android(): string {
|
||||
return this._android;
|
||||
}
|
||||
|
||||
set android(value: string) {
|
||||
this._android = value;
|
||||
}
|
||||
set android(value: string) {
|
||||
this._android = value;
|
||||
}
|
||||
|
||||
public getImageAsync(callback: (image, error) => void) {
|
||||
let bitmapOptions = new android.graphics.BitmapFactory.Options();
|
||||
bitmapOptions.inJustDecodeBounds = true;
|
||||
// read only the file size
|
||||
let bitmap = android.graphics.BitmapFactory.decodeFile(this.android, bitmapOptions);
|
||||
let sourceSize = {
|
||||
width: bitmapOptions.outWidth,
|
||||
height: bitmapOptions.outHeight
|
||||
};
|
||||
let requestedSize = getRequestedImageSize(sourceSize, this.options);
|
||||
public getImageAsync(callback: (image, error) => void) {
|
||||
let bitmapOptions = new android.graphics.BitmapFactory.Options();
|
||||
bitmapOptions.inJustDecodeBounds = true;
|
||||
// read only the file size
|
||||
let bitmap = android.graphics.BitmapFactory.decodeFile(
|
||||
this.android,
|
||||
bitmapOptions
|
||||
);
|
||||
let sourceSize = {
|
||||
width: bitmapOptions.outWidth,
|
||||
height: bitmapOptions.outHeight,
|
||||
};
|
||||
let requestedSize = getRequestedImageSize(sourceSize, this.options);
|
||||
|
||||
let sampleSize = org.nativescript.widgets.image.Fetcher.calculateInSampleSize(bitmapOptions.outWidth, bitmapOptions.outHeight, requestedSize.width, requestedSize.height);
|
||||
let sampleSize = org.nativescript.widgets.image.Fetcher.calculateInSampleSize(
|
||||
bitmapOptions.outWidth,
|
||||
bitmapOptions.outHeight,
|
||||
requestedSize.width,
|
||||
requestedSize.height
|
||||
);
|
||||
|
||||
let finalBitmapOptions = new android.graphics.BitmapFactory.Options();
|
||||
finalBitmapOptions.inSampleSize = sampleSize;
|
||||
try {
|
||||
let error = null;
|
||||
// read as minimum bitmap as possible (slightly bigger than the requested size)
|
||||
bitmap = android.graphics.BitmapFactory.decodeFile(this.android, finalBitmapOptions);
|
||||
let finalBitmapOptions = new android.graphics.BitmapFactory.Options();
|
||||
finalBitmapOptions.inSampleSize = sampleSize;
|
||||
try {
|
||||
let error = null;
|
||||
// read as minimum bitmap as possible (slightly bigger than the requested size)
|
||||
bitmap = android.graphics.BitmapFactory.decodeFile(
|
||||
this.android,
|
||||
finalBitmapOptions
|
||||
);
|
||||
|
||||
if (bitmap) {
|
||||
if (requestedSize.width !== bitmap.getWidth() || requestedSize.height !== bitmap.getHeight()) {
|
||||
// scale to exact size
|
||||
bitmap = android.graphics.Bitmap.createScaledBitmap(bitmap, requestedSize.width, requestedSize.height, true);
|
||||
}
|
||||
if (bitmap) {
|
||||
if (
|
||||
requestedSize.width !== bitmap.getWidth() ||
|
||||
requestedSize.height !== bitmap.getHeight()
|
||||
) {
|
||||
// scale to exact size
|
||||
bitmap = android.graphics.Bitmap.createScaledBitmap(
|
||||
bitmap,
|
||||
requestedSize.width,
|
||||
requestedSize.height,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
const rotationAngle = calculateAngleFromFile(this.android);
|
||||
if (rotationAngle !== 0) {
|
||||
const matrix = new android.graphics.Matrix();
|
||||
matrix.postRotate(rotationAngle);
|
||||
bitmap = android.graphics.Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
}
|
||||
}
|
||||
const rotationAngle = calculateAngleFromFile(this.android);
|
||||
if (rotationAngle !== 0) {
|
||||
const matrix = new android.graphics.Matrix();
|
||||
matrix.postRotate(rotationAngle);
|
||||
bitmap = android.graphics.Bitmap.createBitmap(
|
||||
bitmap,
|
||||
0,
|
||||
0,
|
||||
bitmap.getWidth(),
|
||||
bitmap.getHeight(),
|
||||
matrix,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bitmap) {
|
||||
error = "Asset '" + this.android + "' cannot be found.";
|
||||
}
|
||||
if (!bitmap) {
|
||||
error = "Asset '" + this.android + "' cannot be found.";
|
||||
}
|
||||
|
||||
callback(bitmap, error);
|
||||
}
|
||||
catch (ex) {
|
||||
callback(null, ex);
|
||||
}
|
||||
}
|
||||
callback(bitmap, error);
|
||||
} catch (ex) {
|
||||
callback(null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateAngleFromFile(filename: string) {
|
||||
let rotationAngle = 0;
|
||||
const ei = new android.media.ExifInterface(filename);
|
||||
const orientation = ei.getAttributeInt(android.media.ExifInterface.TAG_ORIENTATION, android.media.ExifInterface.ORIENTATION_NORMAL);
|
||||
let rotationAngle = 0;
|
||||
const ei = new android.media.ExifInterface(filename);
|
||||
const orientation = ei.getAttributeInt(
|
||||
android.media.ExifInterface.TAG_ORIENTATION,
|
||||
android.media.ExifInterface.ORIENTATION_NORMAL
|
||||
);
|
||||
|
||||
switch (orientation) {
|
||||
case android.media.ExifInterface.ORIENTATION_ROTATE_90:
|
||||
rotationAngle = 90;
|
||||
break;
|
||||
case android.media.ExifInterface.ORIENTATION_ROTATE_180:
|
||||
rotationAngle = 180;
|
||||
break;
|
||||
case android.media.ExifInterface.ORIENTATION_ROTATE_270:
|
||||
rotationAngle = 270;
|
||||
break;
|
||||
}
|
||||
switch (orientation) {
|
||||
case android.media.ExifInterface.ORIENTATION_ROTATE_90:
|
||||
rotationAngle = 90;
|
||||
break;
|
||||
case android.media.ExifInterface.ORIENTATION_ROTATE_180:
|
||||
rotationAngle = 180;
|
||||
break;
|
||||
case android.media.ExifInterface.ORIENTATION_ROTATE_270:
|
||||
rotationAngle = 270;
|
||||
break;
|
||||
}
|
||||
|
||||
return rotationAngle;
|
||||
return rotationAngle;
|
||||
}
|
||||
|
||||
20
nativescript-core/image-asset/index.d.ts
vendored
20
nativescript-core/image-asset/index.d.ts
vendored
@@ -1,17 +1,17 @@
|
||||
import { Observable } from "../data/observable";
|
||||
|
||||
export class ImageAsset extends Observable {
|
||||
constructor(asset: any);
|
||||
getImageAsync(callback: (image: any, error: any) => void); //UIImage for iOS and android.graphics.Bitmap for Android
|
||||
ios: any; //PHAsset
|
||||
nativeImage: any; //UIImage for iOS and android.graphics.Bitmap for Android
|
||||
android: any;
|
||||
options: ImageAssetOptions;
|
||||
constructor(asset: any);
|
||||
getImageAsync(callback: (image: any, error: any) => void); //UIImage for iOS and android.graphics.Bitmap for Android
|
||||
ios: any; //PHAsset
|
||||
nativeImage: any; //UIImage for iOS and android.graphics.Bitmap for Android
|
||||
android: any;
|
||||
options: ImageAssetOptions;
|
||||
}
|
||||
|
||||
export interface ImageAssetOptions {
|
||||
width?: number;
|
||||
height?: number;
|
||||
keepAspectRatio?: boolean;
|
||||
autoScaleFactor?: boolean;
|
||||
width?: number;
|
||||
height?: number;
|
||||
keepAspectRatio?: boolean;
|
||||
autoScaleFactor?: boolean;
|
||||
}
|
||||
|
||||
@@ -4,76 +4,101 @@ import { path as fsPath, knownFolders } from "../file-system";
|
||||
export * from "./image-asset-common";
|
||||
|
||||
export class ImageAsset extends ImageAssetBase {
|
||||
private _ios: PHAsset;
|
||||
private _ios: PHAsset;
|
||||
|
||||
constructor(asset: string | PHAsset | UIImage) {
|
||||
super();
|
||||
if (typeof asset === "string") {
|
||||
if (asset.indexOf("~/") === 0) {
|
||||
asset = fsPath.join(knownFolders.currentApp().path, asset.replace("~/", ""));
|
||||
}
|
||||
constructor(asset: string | PHAsset | UIImage) {
|
||||
super();
|
||||
if (typeof asset === "string") {
|
||||
if (asset.indexOf("~/") === 0) {
|
||||
asset = fsPath.join(
|
||||
knownFolders.currentApp().path,
|
||||
asset.replace("~/", "")
|
||||
);
|
||||
}
|
||||
|
||||
this.nativeImage = UIImage.imageWithContentsOfFile(asset);
|
||||
}
|
||||
else if (asset instanceof UIImage) {
|
||||
this.nativeImage = asset;
|
||||
}
|
||||
else {
|
||||
this.ios = asset;
|
||||
}
|
||||
}
|
||||
this.nativeImage = UIImage.imageWithContentsOfFile(asset);
|
||||
} else if (asset instanceof UIImage) {
|
||||
this.nativeImage = asset;
|
||||
} else {
|
||||
this.ios = asset;
|
||||
}
|
||||
}
|
||||
|
||||
get ios(): PHAsset {
|
||||
return this._ios;
|
||||
}
|
||||
get ios(): PHAsset {
|
||||
return this._ios;
|
||||
}
|
||||
|
||||
set ios(value: PHAsset) {
|
||||
this._ios = value;
|
||||
}
|
||||
set ios(value: PHAsset) {
|
||||
this._ios = value;
|
||||
}
|
||||
|
||||
public getImageAsync(callback: (image, error) => void) {
|
||||
if (!this.ios && !this.nativeImage) {
|
||||
callback(null, "Asset cannot be found.");
|
||||
}
|
||||
public getImageAsync(callback: (image, error) => void) {
|
||||
if (!this.ios && !this.nativeImage) {
|
||||
callback(null, "Asset cannot be found.");
|
||||
}
|
||||
|
||||
let srcWidth = this.nativeImage ? this.nativeImage.size.width : this.ios.pixelWidth;
|
||||
let srcHeight = this.nativeImage ? this.nativeImage.size.height : this.ios.pixelHeight;
|
||||
let requestedSize = getRequestedImageSize({ width: srcWidth, height: srcHeight }, this.options);
|
||||
let srcWidth = this.nativeImage
|
||||
? this.nativeImage.size.width
|
||||
: this.ios.pixelWidth;
|
||||
let srcHeight = this.nativeImage
|
||||
? this.nativeImage.size.height
|
||||
: this.ios.pixelHeight;
|
||||
let requestedSize = getRequestedImageSize(
|
||||
{ width: srcWidth, height: srcHeight },
|
||||
this.options
|
||||
);
|
||||
|
||||
if (this.nativeImage) {
|
||||
let newSize = CGSizeMake(requestedSize.width, requestedSize.height);
|
||||
let resizedImage = this.scaleImage(this.nativeImage, newSize);
|
||||
callback(resizedImage, null);
|
||||
if (this.nativeImage) {
|
||||
let newSize = CGSizeMake(requestedSize.width, requestedSize.height);
|
||||
let resizedImage = this.scaleImage(this.nativeImage, newSize);
|
||||
callback(resizedImage, null);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let imageRequestOptions = PHImageRequestOptions.alloc().init();
|
||||
imageRequestOptions.deliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat;
|
||||
imageRequestOptions.networkAccessAllowed = true;
|
||||
let imageRequestOptions = PHImageRequestOptions.alloc().init();
|
||||
imageRequestOptions.deliveryMode =
|
||||
PHImageRequestOptionsDeliveryMode.HighQualityFormat;
|
||||
imageRequestOptions.networkAccessAllowed = true;
|
||||
|
||||
PHImageManager.defaultManager().requestImageForAssetTargetSizeContentModeOptionsResultHandler(this.ios, requestedSize, PHImageContentMode.AspectFit, imageRequestOptions,
|
||||
(image, imageResultInfo) => {
|
||||
if (image) {
|
||||
let resultImage = this.scaleImage(image, requestedSize);
|
||||
callback(resultImage, null);
|
||||
}
|
||||
else {
|
||||
callback(null, imageResultInfo.valueForKey(PHImageErrorKey));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
PHImageManager.defaultManager().requestImageForAssetTargetSizeContentModeOptionsResultHandler(
|
||||
this.ios,
|
||||
requestedSize,
|
||||
PHImageContentMode.AspectFit,
|
||||
imageRequestOptions,
|
||||
(image, imageResultInfo) => {
|
||||
if (image) {
|
||||
let resultImage = this.scaleImage(image, requestedSize);
|
||||
callback(resultImage, null);
|
||||
} else {
|
||||
callback(
|
||||
null,
|
||||
imageResultInfo.valueForKey(PHImageErrorKey)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private scaleImage(image: UIImage, requestedSize: { width: number, height: number }): UIImage {
|
||||
// scaleFactor = 0 takes the scale factor of the devices's main screen.
|
||||
const scaleFactor = this.options && this.options.autoScaleFactor === false ? 1.0 : 0.0;
|
||||
private scaleImage(
|
||||
image: UIImage,
|
||||
requestedSize: { width: number; height: number }
|
||||
): UIImage {
|
||||
// scaleFactor = 0 takes the scale factor of the devices's main screen.
|
||||
const scaleFactor =
|
||||
this.options && this.options.autoScaleFactor === false ? 1.0 : 0.0;
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(requestedSize, false, scaleFactor);
|
||||
image.drawInRect(CGRectMake(0, 0, requestedSize.width, requestedSize.height));
|
||||
let resultImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
UIGraphicsBeginImageContextWithOptions(
|
||||
requestedSize,
|
||||
false,
|
||||
scaleFactor
|
||||
);
|
||||
image.drawInRect(
|
||||
CGRectMake(0, 0, requestedSize.width, requestedSize.height)
|
||||
);
|
||||
let resultImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return resultImage;
|
||||
}
|
||||
return resultImage;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user