Skip to content

Commit a94ec99

Browse files
Dimitar TachevADjenkov
authored andcommitted
Improve ImageAsset scaling (NativeScript#5110)
* Do not depend on current device screen while calculating Image Asset size. * Scale the image asset to the exact requested size. * Process image assets natively, pass keepAspectRatio based on the stretch property and Asset options. * Fixed the splashscreen resource name as it cannot be read when containing a dot. * Updated the Image Asset scale and rotate logic based on the Native one. * Make the ImageAsset size more important than the Image decode size as its more specific. * Fixed tslint errors. * Added filePath support in the ImageAsset constructor for iOS in order to unify it with the Android implementation, support for relative files and file not found support errors. * Added unit tests for ImageAssets. * Added a sample app for UI testing of image-view with ImageAsset src. * chore: apply PR comments
1 parent 27622d8 commit a94ec99

File tree

17 files changed

+262
-21
lines changed

17 files changed

+262
-21
lines changed

apps/app/splashscreen.png

35.4 KB
Loading
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import * as vmModule from "./view-model";
2+
3+
var viewModel = vmModule.imageViewModel;
4+
5+
export function pageLoaded(args) {
6+
let page = args.object;
7+
page.bindingContext = viewModel;
8+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Page loaded="pageLoaded">
2+
<GridLayout rows="*, *">
3+
<Image row="0" src="{{ cameraImageAsset }}" stretch="aspectFill" margin="10"/>
4+
<Image row="1" src="{{ cameraImageSrc }}" stretch="aspectFill" margin="10"></Image>
5+
</GridLayout>
6+
</Page>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import * as dialogs from "tns-core-modules/ui/dialogs";
2+
import * as observable from "tns-core-modules/data/observable";
3+
import * as imageAssetModule from "tns-core-modules/image-asset";
4+
import { ImageSource } from 'tns-core-modules/image-source';
5+
6+
let _cameraImageAsset = null;
7+
let _cameraImageSrc = null;
8+
9+
export class ImageViewModel extends observable.Observable {
10+
11+
constructor() {
12+
super();
13+
let asset = new imageAssetModule.ImageAsset('~/splashscreen.png');
14+
asset.options = {
15+
width: 300,
16+
height: 300,
17+
keepAspectRatio: true
18+
};
19+
let source = new ImageSource();
20+
source.fromAsset(asset).then((source) => {
21+
this.set("cameraImageAsset", asset);
22+
this.set("cameraImageSrc", source);
23+
}, (error) => {
24+
console.log(error);
25+
});
26+
}
27+
28+
get cameraImageAsset(): string {
29+
return _cameraImageAsset;
30+
}
31+
32+
set cameraImageAsset(value: string) {
33+
_cameraImageAsset = value;
34+
}
35+
36+
get cameraImageSrc(): string {
37+
return _cameraImageSrc;
38+
}
39+
40+
set cameraImageSrc(value: string) {
41+
_cameraImageSrc = value;
42+
}
43+
}
44+
export var imageViewModel = new ImageViewModel();

apps/app/ui-tests-app/image-view/main-page.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export function loadExamples() {
1616
examples.set("mode-matrix", "image-view/mode-matrix");
1717
examples.set("stretch-modes", "image-view/stretch-modes");
1818
examples.set("missing-image", "image-view/missing-image");
19+
examples.set("image-asset", "image-view/image-asset/image-asset");
1920

2021
return examples;
2122
}
Binary file not shown.
34.6 KB
Loading
34.6 KB
Loading

tests/app/image-source/image-source-tests.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import * as imageSource from "tns-core-modules/image-source";
2+
import * as imageAssetModule from "tns-core-modules/image-asset";
23
import * as fs from "tns-core-modules/file-system";
34
import * as app from "tns-core-modules/application";
45
import * as TKUnit from "../TKUnit";
56
import * as platform from "tns-core-modules/platform";
67

78
const imagePath = "~/logo.png";
9+
const splashscreenPath = "~/splashscreen.png";
10+
const splashscreenWidth = 372;
11+
const splashscreenHeight = 218;
812
const smallImagePath = "~/small-image.png";
913

1014
export function testFromResource() {
@@ -65,6 +69,96 @@ export function testFromFile() {
6569
TKUnit.assert(!fs.File.exists(path), "test.png not removed");
6670
}
6771

72+
export function testFromAssetFileNotFound(done) {
73+
let asset = new imageAssetModule.ImageAsset('invalidFile.png');
74+
asset.options = {
75+
width: 0,
76+
height: 0,
77+
keepAspectRatio: true
78+
};
79+
80+
let img = imageSource.fromAsset(asset).then((source) => {
81+
done('Should not resolve with invalid file name.');
82+
}, (error) => {
83+
TKUnit.assertNotNull(error);
84+
done();
85+
});
86+
}
87+
88+
export function testFromAssetSimple(done) {
89+
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
90+
asset.options = {
91+
width: 0,
92+
height: 0,
93+
keepAspectRatio: true
94+
};
95+
96+
let img = imageSource.fromAsset(asset).then((source) => {
97+
TKUnit.assertEqual(source.width, splashscreenWidth);
98+
TKUnit.assertEqual(source.height, splashscreenHeight);
99+
done();
100+
}, (error) => {
101+
done(error);
102+
});
103+
}
104+
105+
export function testFromAssetWithScaling(done) {
106+
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
107+
let scaleWidth = 10;
108+
let scaleHeight = 11;
109+
asset.options = {
110+
width: scaleWidth,
111+
height: scaleHeight,
112+
keepAspectRatio: false
113+
};
114+
115+
let img = imageSource.fromAsset(asset).then((source) => {
116+
TKUnit.assertEqual(source.width, scaleWidth);
117+
TKUnit.assertEqual(source.height, scaleHeight);
118+
done();
119+
}, (error) => {
120+
done(error);
121+
});
122+
}
123+
124+
export function testFromAssetWithScalingAndAspectRatio(done) {
125+
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
126+
let scaleWidth = 10;
127+
let scaleHeight = 11;
128+
asset.options = {
129+
width: scaleWidth,
130+
height: scaleHeight,
131+
keepAspectRatio: true
132+
};
133+
134+
let img = imageSource.fromAsset(asset).then((source) => {
135+
TKUnit.assertEqual(source.width, scaleWidth);
136+
TKUnit.assertEqual(source.height, 5);
137+
done();
138+
}, (error) => {
139+
done(error);
140+
});
141+
}
142+
143+
export function testFromAssetWithBiggerScaling(done) {
144+
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
145+
let scaleWidth = 600;
146+
let scaleHeight = 600;
147+
asset.options = {
148+
width: scaleWidth,
149+
height: scaleHeight,
150+
keepAspectRatio: false
151+
};
152+
153+
let img = imageSource.fromAsset(asset).then((source) => {
154+
TKUnit.assertEqual(source.width, scaleWidth);
155+
TKUnit.assertEqual(source.height, scaleHeight);
156+
done();
157+
}, (error) => {
158+
done(error);
159+
});
160+
}
161+
68162
export function testNativeFields() {
69163
const img = imageSource.fromFile(imagePath);
70164
if (app.android) {

tests/app/splashscreen.png

34.6 KB
Loading

0 commit comments

Comments
 (0)