angular - Nativescript 图像缩略图
问题描述
我正在使用带有 NativeScript 相机插件的 Angular 8.0 + NativeScript 6.0 来拍照并将它们存储在我的应用程序的图库中。当我列出我在应用程序中拍摄的图像时,它会加载全尺寸图像,这会减慢整个应用程序的速度。
有没有办法获得画廊图像的缩略图而不是完整图像?
目前,我通过将完整图像的 URL 存储在名为receipt_url 的字符串中并将其传递给后端来将完整图像的URL 保存在我的数据库中。这是我拍照并存储 URL 的代码;
onTakeReceiptTap(args) {
requestPermissions().then(
() => {
takePicture({width: 640, height: 480, keepAspectRatio: true})
.then((imageAsset: any) => {
this.receiptImage = imageAsset;
console.log("Taken receipt")
let that = this;
if (imageAsset.android) {
this._dataItem.receipt_url = imageAsset.android;
} else if (imageAsset.ios) {
this._dataItem.receipt_url = imageAsset.ios;
}
}, (error) => {
console.log("Error: " + error);
});
},
() => alert('permissions rejected')
);
} // onTakeReceiptTap
执行列表时,我只需从数据库中获取所有记录,其中包括收据 url,然后像这样显示图片;
<Image rowspan="2" col="1" [src]="item.receipt_url" stretch="aspectFit"></Image>
鉴于我所拥有的只是一个 URL,我想知道 Android/iOS 是否创建一个缩略图,我可以在其中获取 URL 并将其存储并在我的列表中使用,或者我是否必须以某种方式自己创建缩略图并发送来自后端的缩略图还是保存缩略图的 URL?
更新:虚拟滚动
我尝试像这样添加虚拟滚动,并尝试了不同的高度(150、500 和 1000),所有这些滚动仍然非常缓慢且生涩。
<GridLayout row="1" columns="*, auto">
<RadListView [items]="dataItems"
[filteringFunction]="filterItems"
pullToRefresh="true"
(pullToRefreshInitiated)="onPullToRefreshInitiated($event)">
<ScrollView height="500">
<ng-template tkListItemTemplate let-item="item">
<StackLayout orientation="vertical">
<GridLayout class="itemContainer" rows="50,*" columns="*,100">
<!-- Currently these images are full size and slowing down the listing -->
<Image rowspan="2" col="1" [src]="item.picture_url" stretch="aspectFit"></Image>
<Label row="0" col="0" class="nameLabel" [text]="item.name"></Label>
</GridLayout>
<!-- <StackLayout orientation="horizontal">
<Label text="Price: "></Label>
<Label class="gross_centsLabel" [text]="item.gross_cents"></Label>
</StackLayout> -->
</StackLayout>
</ng-template>
</ScrollView>
</RadListView>
</GridLayout>
更新:使用 ImageSource
如果我尝试对列表中的每个图像使用 ImageSource,则会收到以下错误;
LOG from device Galaxy S8: ERROR Error: java.lang.OutOfMemoryError: Failed to allocate a 36578316 byte allocation with 16269904 free bytes and 15MB until OOM
这是我设置 ImageSources 的方式;
loadData() {
this._dataItemService.listing()
.subscribe(loadedItems => {
loadedItems.forEach((itemObject) => {
itemObject.picture = fromFile(itemObject.picture_url);
this._dataItems.unshift(itemObject) ;
});
})
}
'picture' 属性在数据模型中设置为 ImageSource。
更新:保存缩略图
我设法在前端保存了一个缩略图并将其显示在我的列表中。现在上市速度要快得多。
const source = new ImageSource();
source.fromAsset(imageAsset)
.then((imageSource: ImageSource) => {
const folderPath = knownFolders.documents().path;
const fileName = "test.jpg";
const filePath = path.join(folderPath, fileName);
const saved: boolean = imageSource.saveToFile(filePath, "jpg");
if (saved) {
console.log("Gallery: " + this._dataItem.picture_url);
console.log("Saved: " + filePath);
console.log("Image saved successfully!");
}
});
解决方案
如前所述,您可以在后端创建缩略图。我建议使用Sharp(或libvips)更快。
您可以做的另一件好事是避免使用*ngFor
您知道会变得冗长的列表。改为使用ListView
。
ListView
回收视图并仅渲染/加载应用程序需要的视图。从而避免加载到不可见的内存视图中。
<ListView [items]="countries" (itemTap)="onItemTap($event)" class="list-group">
<ng-template let-item="item">
<GridLayout class="itemContainer" rows="50,*" columns="*,100">
<!-- Currently these images are full size and slowing down the listing -->
<Image rowspan="2" col="1" [src]="item.picture_url" stretch="aspectFit"></Image>
<Label row="0" col="0" class="nameLabel" [text]="item.name"></Lab
</GridLayout>
</ng-template>
</ListView>
更新:修复RadListView
实现
在您的 实现中RadListView
,有一个ScrollView
内部。
请记住:
- 在 RadListView 内,您必须仅使用项目的模板:
<ng-template tkListItemTemplate let-item="item">...
- (
RadListView
as theListView
) 是一个滚动小部件。你不需要一个ScrollView
.
<RadListView [items]="dataItems"
[filteringFunction]="filterItems"
pullToRefresh="true"
(pullToRefreshInitiated)="onPullToRefreshInitiated($event)">
<ng-template tkListItemTemplate let-item="item">
<GridLayout class="itemContainer" rows="50,*" columns="*,100">
<!-- Currently these images are full size and slowing down the listing -->
<Image rowspan="2" col="1" [src]="item.picture_url" stretch="aspectFit"></Image>
<Label row="0" col="0" class="nameLabel" [text]="item.name"></Label>
</GridLayout>
</ng-template>
</RadListView>
推荐阅读
- protocol-buffers - grpc服务中如何区分未提供和空数组?
- express - 带有 NextJs 的 Github webhook
- c# - 使用 iText 导出为 PDF 不显示来自 GridView 的完整数据
- reactjs - 在 react.js 中使用 API 获取数据
- caching - Neo4j 整个图未加载到页面缓存中
- nlp - 如何创建NLP(自然语言处理领域语言)模型.....?
- javascript - 我需要更换在字符串中标记该标记 java 脚本中的内容
- python-3.x - Nonetype 对象没有属性“用户”
- graphql - 有没有办法从 graphql.js 解析器的信息重建查询?
- scadalts - 备份无法运行