mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-20 23:42:50 +08:00
feat(image-source): add saveToFileAsync, toBase64StringAsync & resizeAsync (#9404)
This commit is contained in:

committed by
Nathan Walker

parent
3aff057b99
commit
b2f792324d
@ -316,6 +316,29 @@ export class ImageSource implements ImageSourceDefinition {
|
||||
return res;
|
||||
}
|
||||
|
||||
public saveToFileAsync(path: string, format: 'png' | 'jpeg' | 'jpg', quality = 100): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
org.nativescript.widgets.Utils.saveToFileAsync(
|
||||
this.android,
|
||||
path,
|
||||
format,
|
||||
quality,
|
||||
new org.nativescript.widgets.Utils.AsyncImageCallback({
|
||||
onSuccess(param0: boolean) {
|
||||
resolve(param0);
|
||||
},
|
||||
onError(param0: java.lang.Exception) {
|
||||
if (param0) {
|
||||
reject(param0.getMessage());
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public toBase64String(format: 'png' | 'jpeg' | 'jpg', quality = 100): string {
|
||||
if (!this.android) {
|
||||
return null;
|
||||
@ -334,12 +357,56 @@ export class ImageSource implements ImageSourceDefinition {
|
||||
return outputStream.toString();
|
||||
}
|
||||
|
||||
public toBase64StringAsync(format: 'png' | 'jpeg' | 'jpg', quality = 100): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
org.nativescript.widgets.Utils.toBase64StringAsync(
|
||||
this.android,
|
||||
format,
|
||||
quality,
|
||||
new org.nativescript.widgets.Utils.AsyncImageCallback({
|
||||
onSuccess(param0: string) {
|
||||
resolve(param0);
|
||||
},
|
||||
onError(param0: java.lang.Exception) {
|
||||
if (param0) {
|
||||
reject(param0.getMessage());
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public resize(maxSize: number, options?: any): ImageSource {
|
||||
const dim = getScaledDimensions(this.android.getWidth(), this.android.getHeight(), maxSize);
|
||||
const bm: android.graphics.Bitmap = android.graphics.Bitmap.createScaledBitmap(this.android, dim.width, dim.height, options && options.filter);
|
||||
|
||||
return new ImageSource(bm);
|
||||
}
|
||||
|
||||
public resizeAsync(maxSize: number, options?: any): Promise<ImageSource> {
|
||||
return new Promise((resolve, reject) => {
|
||||
org.nativescript.widgets.Utils.resizeAsync(
|
||||
this.android,
|
||||
maxSize,
|
||||
JSON.stringify(options || {}),
|
||||
new org.nativescript.widgets.Utils.AsyncImageCallback({
|
||||
onSuccess(param0: any) {
|
||||
resolve(new ImageSource(param0));
|
||||
},
|
||||
onError(param0: java.lang.Exception) {
|
||||
if (param0) {
|
||||
reject(param0.getMessage());
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getTargetFormat(format: 'png' | 'jpeg' | 'jpg'): android.graphics.Bitmap.CompressFormat {
|
||||
|
28
packages/core/image-source/index.d.ts
vendored
28
packages/core/image-source/index.d.ts
vendored
@ -198,6 +198,14 @@ export class ImageSource {
|
||||
*/
|
||||
saveToFile(path: string, format: 'png' | 'jpeg' | 'jpg', quality?: number): boolean;
|
||||
|
||||
/**
|
||||
* Saves this instance to the specified file, using the provided image format and quality asynchronously.
|
||||
* @param path The path of the file on the file system to save to.
|
||||
* @param format The format (encoding) of the image.
|
||||
* @param quality Optional parameter, specifying the quality of the encoding. Defaults to the maximum available quality. Quality varies on a scale of 0 to 100.
|
||||
*/
|
||||
saveToFileAsync(path: string, format: 'png' | 'jpeg' | 'jpg', quality?: number): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Converts the image to base64 encoded string, using the provided image format and quality.
|
||||
* @param format The format (encoding) of the image.
|
||||
@ -205,6 +213,13 @@ export class ImageSource {
|
||||
*/
|
||||
toBase64String(format: 'png' | 'jpeg' | 'jpg', quality?: number): string;
|
||||
|
||||
/**
|
||||
* Converts the image to base64 encoded string, using the provided image format and quality asynchronously.
|
||||
* @param format The format (encoding) of the image.
|
||||
* @param quality Optional parameter, specifying the quality of the encoding. Defaults to the maximum available quality. Quality varies on a scale of 0 to 100.
|
||||
*/
|
||||
toBase64StringAsync(format: 'png' | 'jpeg' | 'jpg', quality?: number): Promise<string>;
|
||||
|
||||
/**
|
||||
* Returns a new ImageSource that is a resized version of this image with the same aspect ratio, but the max dimension set to the provided maxSize.
|
||||
* @param maxSize The maximum pixel dimension of the resulting image.
|
||||
@ -217,6 +232,19 @@ export class ImageSource {
|
||||
* bilinear filtering is typically minimal and the improved image quality is significant.
|
||||
*/
|
||||
resize(maxSize: number, options?: any): ImageSource;
|
||||
|
||||
/**
|
||||
* Returns a new ImageSource that is a resized version of this image with the same aspect ratio, but the max dimension set to the provided maxSize asynchronously.
|
||||
* @param maxSize The maximum pixel dimension of the resulting image.
|
||||
* @param options Optional parameter, Only used for android, options.filter is a boolean which
|
||||
* determines whether or not bilinear filtering should be used when scaling the bitmap.
|
||||
* If this is true then bilinear filtering will be used when scaling which has
|
||||
* better image quality at the cost of worse performance. If this is false then
|
||||
* nearest-neighbor scaling is used instead which will have worse image quality
|
||||
* but is faster. Recommended default is to set filter to 'true' as the cost of
|
||||
* bilinear filtering is typically minimal and the improved image quality is significant.
|
||||
*/
|
||||
resizeAsync(maxSize: number, options?: any): Promise<ImageSource>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -317,6 +317,33 @@ export class ImageSource implements ImageSourceDefinition {
|
||||
return false;
|
||||
}
|
||||
|
||||
public saveToFileAsync(path: string, format: 'png' | 'jpeg' | 'jpg', quality?: number): Promise<boolean> {
|
||||
return new Promise<boolean>((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(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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public toBase64String(format: 'png' | 'jpeg' | 'jpg', quality?: number): string {
|
||||
let res = null;
|
||||
if (!this.ios) {
|
||||
@ -335,6 +362,33 @@ export class ImageSource implements ImageSourceDefinition {
|
||||
return res;
|
||||
}
|
||||
|
||||
public toBase64StringAsync(format: 'png' | 'jpeg' | 'jpg', quality?: number): Promise<string> {
|
||||
return new Promise<string>((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(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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public resize(maxSize: number, options?: any): ImageSource {
|
||||
const size: CGSize = this.ios.size;
|
||||
const dim = getScaledDimensions(size.width, size.height, maxSize);
|
||||
@ -349,6 +403,31 @@ export class ImageSource implements ImageSourceDefinition {
|
||||
|
||||
return new ImageSource(resizedImage);
|
||||
}
|
||||
|
||||
public resizeAsync(maxSize: number, options?: any): Promise<ImageSource> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.ios) {
|
||||
reject(null);
|
||||
}
|
||||
const main_queue = dispatch_get_current_queue();
|
||||
const background_queue = dispatch_get_global_queue(qos_class_t.QOS_CLASS_DEFAULT, 0);
|
||||
dispatch_async(background_queue, () => {
|
||||
const size: CGSize = this.ios.size;
|
||||
const dim = getScaledDimensions(size.width, size.height, maxSize);
|
||||
|
||||
const newSize: CGSize = 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: string): string {
|
||||
|
Binary file not shown.
Reference in New Issue
Block a user