mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-20 23:42:50 +08:00
feat(core): nativescript.config and webpack updates (#8801)
This commit is contained in:
16
apps/automated/src/image-source/image-source-snippet.ts
Normal file
16
apps/automated/src/image-source/image-source-snippet.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { ImageSource } from '@nativescript/core/image-source';
|
||||
import * as fs from '@nativescript/core/file-system';
|
||||
// >> imagesource-from-imageasset-save-to
|
||||
|
||||
export function imageSourceFromAsset(imageAsset) {
|
||||
ImageSource.fromAsset(imageAsset).then((imageSource) => {
|
||||
let folder = fs.knownFolders.documents().path;
|
||||
let fileName = 'test.png';
|
||||
let path = fs.path.join(folder, fileName);
|
||||
let saved = imageSource.saveToFile(path, 'png');
|
||||
if (saved) {
|
||||
console.log('Image saved successfully!');
|
||||
}
|
||||
});
|
||||
}
|
||||
// << imagesource-from-imageasset-save-to
|
315
apps/automated/src/image-source/image-source-tests.ts
Normal file
315
apps/automated/src/image-source/image-source-tests.ts
Normal file
@ -0,0 +1,315 @@
|
||||
import { ImageSource } from '@nativescript/core/image-source';
|
||||
import * as imageAssetModule from '@nativescript/core/image-asset';
|
||||
import * as fs from '@nativescript/core/file-system';
|
||||
import * as app from '@nativescript/core/application';
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import { Font } from '@nativescript/core/ui/styling/font';
|
||||
import { Color } from '@nativescript/core/color';
|
||||
|
||||
const imagePath = '~/assets/logo.png';
|
||||
const splashscreenPath = '~/assets/splashscreen.png';
|
||||
const splashscreenWidth = 372;
|
||||
const splashscreenHeight = 218;
|
||||
const smallImagePath = '~/assets/small-image.png';
|
||||
|
||||
export function testFromResource() {
|
||||
// >> imagesource-resname
|
||||
const img = ImageSource.fromResourceSync('icon');
|
||||
// << imagesource-resname
|
||||
|
||||
TKUnit.assert(img.height > 0, 'image.fromResource failed');
|
||||
}
|
||||
|
||||
export function testFromUrl(done) {
|
||||
let result: ImageSource;
|
||||
|
||||
// Deprecated method fromUrl
|
||||
ImageSource.fromUrl('https://www.google.com/images/errors/logo_sm_2.png').then(
|
||||
(res: ImageSource) => {
|
||||
// console.log("Image successfully loaded");
|
||||
// completed = true;
|
||||
result = res;
|
||||
try {
|
||||
TKUnit.assertNotEqual(result, undefined, 'Image not downloaded');
|
||||
TKUnit.assert(result.height > 0, 'Image not downloaded');
|
||||
done(null);
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
// console.log("Error loading image: " + error);
|
||||
//completed = true;
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testSaveToFile() {
|
||||
// >> imagesource-save-to
|
||||
const img = ImageSource.fromFileSync(imagePath);
|
||||
const folder = fs.knownFolders.documents();
|
||||
const path = fs.path.join(folder.path, 'test.png');
|
||||
const saved = img.saveToFile(path, 'png');
|
||||
// << imagesource-save-to
|
||||
TKUnit.assert(saved, 'Image not saved to file');
|
||||
TKUnit.assert(fs.File.exists(path), 'Image not saved to file');
|
||||
}
|
||||
|
||||
export function testSaveToFile_WithQuality() {
|
||||
const img = ImageSource.fromFileSync(imagePath);
|
||||
const folder = fs.knownFolders.documents();
|
||||
const path = fs.path.join(folder.path, 'test.png');
|
||||
const saved = img.saveToFile(path, 'png', 70);
|
||||
TKUnit.assert(saved, 'Image not saved to file');
|
||||
TKUnit.assert(fs.File.exists(path), 'Image not saved to file');
|
||||
}
|
||||
|
||||
export function testFromFile() {
|
||||
// >> imagesource-load-local
|
||||
const folder = fs.knownFolders.documents();
|
||||
const path = fs.path.join(folder.path, 'test.png');
|
||||
const img = ImageSource.fromFileSync(path);
|
||||
// << imagesource-load-local
|
||||
|
||||
TKUnit.assert(img.height > 0, 'image.fromResource failed');
|
||||
|
||||
// remove the image from the file system
|
||||
const file = folder.getFile('test.png');
|
||||
file.remove();
|
||||
TKUnit.assert(!fs.File.exists(path), 'test.png not removed');
|
||||
}
|
||||
|
||||
export function testFromAssetFileNotFound(done) {
|
||||
let asset = new imageAssetModule.ImageAsset('invalidFile.png');
|
||||
asset.options = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
keepAspectRatio: true,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
done('Should not resolve with invalid file name.');
|
||||
},
|
||||
(error) => {
|
||||
TKUnit.assertNotNull(error);
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetSimple(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
asset.options = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
keepAspectRatio: true,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, splashscreenWidth);
|
||||
TKUnit.assertEqual(source.height, splashscreenHeight);
|
||||
done();
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetWithExactScaling(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
let scaleWidth = 10;
|
||||
let scaleHeight = 11;
|
||||
asset.options = {
|
||||
width: scaleWidth,
|
||||
height: scaleHeight,
|
||||
keepAspectRatio: false,
|
||||
autoScaleFactor: false,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, scaleWidth);
|
||||
TKUnit.assertEqual(source.height, scaleHeight);
|
||||
|
||||
const targetFilename = `splashscreenTemp.png`;
|
||||
const tempPath = fs.knownFolders.temp().path;
|
||||
const localFullPath = fs.path.join(tempPath, targetFilename);
|
||||
|
||||
const fullImageSaved = source.saveToFile(localFullPath, 'png');
|
||||
|
||||
if (fullImageSaved) {
|
||||
ImageSource.fromFile(localFullPath).then((sourceImage) => {
|
||||
TKUnit.assertEqual(sourceImage.width, scaleWidth);
|
||||
TKUnit.assertEqual(sourceImage.height, scaleHeight);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
done(`Error saving photo to local temp folder: ${localFullPath}`);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetWithScalingAndAspectRatio(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
let scaleWidth = 10;
|
||||
let scaleHeight = 11;
|
||||
asset.options = {
|
||||
width: scaleWidth,
|
||||
height: scaleHeight,
|
||||
keepAspectRatio: true,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, 18);
|
||||
TKUnit.assertEqual(source.height, scaleHeight);
|
||||
done();
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetWithScalingAndDefaultAspectRatio(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
let scaleWidth = 10;
|
||||
let scaleHeight = 11;
|
||||
asset.options.width = scaleWidth;
|
||||
asset.options.height = scaleHeight;
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, 18);
|
||||
TKUnit.assertEqual(source.height, scaleHeight);
|
||||
done();
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetWithBiggerScaling(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
let scaleWidth = 600;
|
||||
let scaleHeight = 600;
|
||||
asset.options = {
|
||||
width: scaleWidth,
|
||||
height: scaleHeight,
|
||||
keepAspectRatio: false,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, scaleWidth);
|
||||
TKUnit.assertEqual(source.height, scaleHeight);
|
||||
done();
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testNativeFields() {
|
||||
const img = ImageSource.fromFileSync(imagePath);
|
||||
if (app.android) {
|
||||
TKUnit.assert(img.android != null, 'Image.android not updated.');
|
||||
} else if (app.ios) {
|
||||
TKUnit.assert(img.ios != null, 'Image.ios not updated.');
|
||||
}
|
||||
}
|
||||
const fullAndroidPng = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAA3NCSVQICAjb4U/gAAAAFUlEQVQImWP8z4AAjAz/kTnIPGQAAG86AwGcuMlCAAAAAElFTkSuQmCC';
|
||||
const fullIosPng = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c6QAAABxpRE9UAAAAAgAAAAAAAAACAAAAKAAAAAIAAAACAAAARiS4uJEAAAASSURBVBgZYvjPwABHSMz/DAAAAAD//0GWpK0AAAAOSURBVGNgYPiPhBgQAACEvQv1D5y/pAAAAABJRU5ErkJggg==';
|
||||
|
||||
const jpgImageAsBase64String =
|
||||
'/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAEAAQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+Pz/h5j+1Z/z9fBr/AMRt+AH/AM7uiiiv9fV9E36KOn/HMX0f+n/NlvDT/p3/ANUv/V3vrf8AP1nueaf8LOa9P+ZjjP8Ap3/0/wD6u99b/wD/2Q==';
|
||||
const expectedJpegStart = '/9j/4AAQSkZJRgAB';
|
||||
const expectedPngStart = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAA';
|
||||
|
||||
export function testBase64Encode_PNG() {
|
||||
// >> imagesource-to-base-string
|
||||
const img = ImageSource.fromFileSync(smallImagePath);
|
||||
let base64String = img.toBase64String('png');
|
||||
// << imagesource-to-base-string
|
||||
|
||||
base64String = base64String.substr(0, expectedPngStart.length);
|
||||
TKUnit.assertEqual(base64String, expectedPngStart, 'Base 64 encoded PNG');
|
||||
}
|
||||
|
||||
export function testBase64Encode_PNG_WithQuality() {
|
||||
const img = ImageSource.fromFileSync(smallImagePath);
|
||||
let base64String = img.toBase64String('png', 80);
|
||||
base64String = base64String.substr(0, expectedPngStart.length);
|
||||
TKUnit.assertEqual(base64String, expectedPngStart, 'Base 64 encoded PNG');
|
||||
}
|
||||
|
||||
export function testBase64Encode_JPEG() {
|
||||
const img = ImageSource.fromFileSync(smallImagePath);
|
||||
|
||||
let base64String = img.toBase64String('jpeg');
|
||||
base64String = base64String.substr(0, expectedJpegStart.length);
|
||||
|
||||
TKUnit.assertEqual(base64String, expectedJpegStart, 'Base 64 encoded JPEG');
|
||||
}
|
||||
|
||||
export function testBase64Encode_JPEG_With_Quality() {
|
||||
const img = ImageSource.fromFileSync(smallImagePath);
|
||||
|
||||
let base64String = img.toBase64String('jpeg', 80);
|
||||
base64String = base64String.substr(0, expectedJpegStart.length);
|
||||
|
||||
TKUnit.assertEqual(base64String, expectedJpegStart, 'Base 64 encoded JPEG');
|
||||
}
|
||||
|
||||
export function testLoadFromBase64Encode_JPEG() {
|
||||
// >> imagesource-from-base-string
|
||||
let img: ImageSource;
|
||||
img = ImageSource.fromBase64Sync(jpgImageAsBase64String);
|
||||
// << imagesource-from-base-string
|
||||
|
||||
TKUnit.assert(img !== null, 'Actual: ' + img);
|
||||
TKUnit.assertEqual(img.width, 4, 'img.width');
|
||||
TKUnit.assertEqual(img.height, 4, 'img.height');
|
||||
}
|
||||
|
||||
export function testLoadFromBase64Encode_PNG() {
|
||||
let img: ImageSource;
|
||||
if (app.android) {
|
||||
img = ImageSource.fromBase64Sync(fullAndroidPng);
|
||||
} else if (app.ios) {
|
||||
img = ImageSource.fromBase64Sync(fullIosPng);
|
||||
}
|
||||
|
||||
TKUnit.assert(img !== null, 'Actual: ' + img);
|
||||
TKUnit.assertEqual(img.width, 4, 'img.width');
|
||||
TKUnit.assertEqual(img.height, 4, 'img.height');
|
||||
}
|
||||
|
||||
export function testLoadFromFontIconCode() {
|
||||
let img: ImageSource;
|
||||
img = ImageSource.fromFontIconCodeSync('F10B', Font.default.withFontFamily('FontAwesome'), new Color('red'));
|
||||
|
||||
TKUnit.assert(img !== null, 'Actual: ' + img);
|
||||
TKUnit.assert(img.width !== null, 'img.width');
|
||||
TKUnit.assert(img.height !== null, 'img.width');
|
||||
}
|
||||
|
||||
export function testResize() {
|
||||
const img = ImageSource.fromFileSync(imagePath);
|
||||
|
||||
const newSize = Math.floor(Math.max(img.width, img.height) / 2);
|
||||
|
||||
const resized = img.resize(newSize);
|
||||
|
||||
TKUnit.assert(resized.width === newSize || resized.height === newSize, 'Image not resized correctly');
|
||||
}
|
56
apps/automated/src/image-source/image-source.md
Normal file
56
apps/automated/src/image-source/image-source.md
Normal file
@ -0,0 +1,56 @@
|
||||
---
|
||||
nav-title: "image-source How-To"
|
||||
title: "image-source"
|
||||
environment: nativescript
|
||||
description: "Examples for using image-source"
|
||||
previous_url: /ApiReference/image-source/HOW-TO
|
||||
---
|
||||
# Image source
|
||||
Using the image source requires the image-source module.
|
||||
```TypeScript
|
||||
import * as imageSource from "tns-core-modules/image-source";
|
||||
```
|
||||
```JavaScript
|
||||
var imageSource = require("tns-core-modules/image-source");
|
||||
```
|
||||
The pre-required `imageSource` module is used throughout the following code snippets.
|
||||
We also use fs module defined as follows:
|
||||
```TypeScript
|
||||
import * as fs from "tns-core-modules/file-system";
|
||||
```
|
||||
```JavaScript
|
||||
var fs = require("tns-core-modules/file-system");
|
||||
```
|
||||
|
||||
## Loading and saving images
|
||||
|
||||
### Load image using resource name
|
||||
This is similar to loading Bitmap from `R.drawable.logo` on Android or calling `[UIImage imageNamed@"logo"]` on iOS.
|
||||
The method `fromResource` creates an `ImageSource` instance and loads it from the specified resource name.
|
||||
{%snippet imagesource-resname%}
|
||||
|
||||
### Save image to PNG or JPG file
|
||||
The method `saveToFile(path: string, format: "png" | "jpeg" | "jpg", quality?: number): boolean` saves `ImageSource` instance to the specified file, using the provided image format and quality.
|
||||
The supported formats are `png`, `jpeg`, and `jpg`. The quality parameter is optional and defaults to maximum quality. Returns `true` if the file is saved successfully.
|
||||
{%snippet imagesource-save-to%}
|
||||
|
||||
### Load image from a local file
|
||||
Use `fromFile(path: string): Promise<boolean>` to load an `ImageSource` instance from the specified file asynchronously.
|
||||
{%snippet imagesource-load-local%}
|
||||
|
||||
### Load image from URL
|
||||
Use `http.getImage(url: string): Promise<ImageSource>` to fetch `ImageSource` from online source.
|
||||
{%snippet http-get-image%}
|
||||
|
||||
### Save image from image asset to PNG file
|
||||
Use `fromAsset(asset: ImageAsset): Promise<ImageSource>` to load `ImageSource` from the specified `ImageAsset` asynchronously.
|
||||
{%snippet imagesource-from-imageasset-save-to%}
|
||||
|
||||
### Creating base64 string from PNG image file
|
||||
The method `toBase64String(format: "png" | "jpeg" | "jpg", quality?: number): string` converts the image to base64 encoded string, using the provided image format and quality.
|
||||
The supported formats are `png`, `jpeg`, and `jpg`. The quality parameter is optional and defaults to maximum quality.
|
||||
{%snippet imagesource-to-base-string%}
|
||||
|
||||
### Creating PNG image file from base64 string
|
||||
The method `fromBase64(source: string): Promise<boolean>` loads this instance from the specified base64 encoded string asynchronously.
|
||||
{%snippet imagesource-from-base-string%}
|
Reference in New Issue
Block a user