diff --git a/SimpleChatList/entry/src/main/ets/pages/ScrollToTheBottom.ets b/SimpleChatList/entry/src/main/ets/pages/ScrollToTheBottom.ets index cd72ae58e04ac50d16e9c77eefb2bc6c56b33d56..3d4d75a3c38dce7abc46ed4c0c1e65022332a686 100644 --- a/SimpleChatList/entry/src/main/ets/pages/ScrollToTheBottom.ets +++ b/SimpleChatList/entry/src/main/ets/pages/ScrollToTheBottom.ets @@ -28,7 +28,8 @@ struct ScrollToTheBottom { // [EndExclude Scroller] // [Start initialIndex] List({ space: 20, initialIndex: this.arr.length - 1, scroller: this.scroller }) { - // [End Scroller] + // [StartExclude Scroller] + ForEach(this.arr, (item: number) => { ListItem() { // [StartExclude initialIndex] @@ -44,7 +45,9 @@ struct ScrollToTheBottom { .borderRadius(16) .backgroundColor(0xDCDCDC) }, (item: string) => item) + // [EndExclude Scroller] } + // [End Scroller] // [End initialIndex] .scrollBar(BarState.Off) .friction(0.6) diff --git a/TextureHypercompression/README.md b/TextureHypercompression/README.md index a2ef03d9b497ec49b2737712e73308918bed2ae7..b24d6956f0ce5d09ded2f8d56c488057173ff622 100644 --- a/TextureHypercompression/README.md +++ b/TextureHypercompression/README.md @@ -1,37 +1,40 @@ -# 纹理压缩提高应用性能 +# 图片资源加载优化提高应用性能 ### 介绍 -本示例介绍了使用纹理压缩技术将预置图片在构建过程中进行转码和压缩,节省CPU的处理过程,减少占用内存,提升应用性能。 +本示例介绍了使用纹理压缩技术将预置图片在构建过程中进行转码和压缩,使用CDN优化网络图片资源、desiredSize对pixelmap进行降采样、autoResize对Image组件进行降采样,节省CPU的处理过程,减少占用内存,提升应用性能。 ### 效果图预览 - -![](./screenshots/device/texture.gif) + ##### 使用说明 -向右滑动切换tab1页面到tab2页面,展示tab2页面中的所有图片。 +1. 点击首页“使用纹理压缩优化预置图片”按钮,进入二级页面,向右滑动切换tab1页面到tab2页面,展示tab2页面中的所有图片。 +2. 点击首页“使用CDN优化网络图片资源”按钮,进入二级页面,替换使用CDN网络图片,查看CDN网络图片。 +3. 点击首页“使用desiredSize对pixelmap进行降采样”按钮,进入二级页面,点击按钮选择相册图片并上传。 +4. 点击首页“使用autoResize对Image组件进行降采样”按钮,进入二级页面,点击按钮选择相册图片并上传。 ### 工程目录 ``` ├──entry/src/main/ets/ │ ├──entryability -│ │ └──EntryAbility.ets // 程序入口类 -│ └──pages -│ └──Index.ets // 首页 +│ │ └──EntryAbility.ets // 程序入口类 +│ └──pages +│ ├──DownsampleThePixelmapUsingDesiredSize.ets // 视图层-使用desiredSize对pixelmap进行降采样 +│ ├──Index.ets // 首页 +│ ├──OptimizeWebImagesUsingCDN.ets // 视图层-使用CDN优化网络图片资源 +│ ├──TextureCompression.ets // 视图层-使用纹理压缩优化预置图片 +│ └──UseAutoResizeToDownsampleTheImageComponent.ets // 视图层-使用autoResize对Image组件进行降采样 └──entry/src/main/resources // 应用静态资源目录 ``` ### 具体实现 -1. 创建Tabs组件,使用TabContent创建tab1和tab2两个标签页。 - -2. 使用@Builder创建tabBuilder自定义构建函数,将tabBuilder传入TabContent的tabBar属性中实现自定义tab栏样式。 - -3. 在tab2页面内使用Image组件加载80张内置图片。 - -4. 在build-profile.json5配置参数开启纹理压缩。 +1. 使用纹理压缩优化预置图片:首先创建Tabs组件,使用TabContent创建tab1和tab2两个标签页。 然后使用@Builder创建tabBuilder自定义构建函数,将tabBuilder传入TabContent的tabBar属性中实现自定义tab栏样式,在tab2页面内使用Image组件加载80张内置图片。 最后,在build-profile.json5配置参数开启纹理压缩。 +2. 使用CDN优化网络图片资源:选择一个CDN服务器,通过图片请求地址添加图片宽高等参数,例如"https://******.com/path/to/image.jpg?w=200&h=150&fit=cover&q=85&format=webp","******"替换为实际CDN服务器域名。 +3. 使用desiredSize对pixelmap进行降采样:使用imageSource.createPixelMap接口,给图片添加DecodingOptions图像解码设置选项,设置期望输出大小desiredSize。 +4. 使用autoResize对Image组件进行降采样:给Image组件设置autoResize,即图片解码过程中是否对图源自动缩放,设置为true时,组件会根据显示区域的尺寸决定用于绘制的图源尺寸,有利于减少内存占用。 ### 相关权限 diff --git a/TextureHypercompression/entry/src/main/ets/pages/DownsampleThePixelmapUsingDesiredSize.ets b/TextureHypercompression/entry/src/main/ets/pages/DownsampleThePixelmapUsingDesiredSize.ets new file mode 100644 index 0000000000000000000000000000000000000000..3e00e563996440628567c72af1d9166120bc0171 --- /dev/null +++ b/TextureHypercompression/entry/src/main/ets/pages/DownsampleThePixelmapUsingDesiredSize.ets @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { BusinessError } from "@kit.BasicServicesKit"; +import { image } from "@kit.ImageKit"; +import { fileIo } from "@kit.CoreFileKit"; +import { photoAccessHelper } from "@kit.MediaLibraryKit"; + +@Component +export struct DownsampleThePixelmapUsingDesiredSize { + // [Start DownsampleThePixelmapUsingDesiredSize] + @State pixel: image.PixelMap | undefined = undefined; + + build() { + NavDestination() { + Column() { + Image(this.pixel) + .objectFit(ImageFit.None) + .width(300) + .height('30%') + + Button('Select image').onClick(() => { + try { + // Select album images. + let uris: Array = []; + let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); + PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; + PhotoSelectOptions.maxSelectNumber = 1; + let photoPicker = new photoAccessHelper.PhotoViewPicker(); + photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => { + uris = PhotoSelectResult.photoUris; + let file = fileIo.openSync(uris[0], fileIo.OpenMode.READ_ONLY); + console.info('file fd: ' + file.fd); + let buffer = new ArrayBuffer(4096); + let readLen = fileIo.readSync(file.fd, buffer); + console.info('readSync data to file succeed and buffer size is:' + readLen); + const imageSource: image.ImageSource = image.createImageSource(file.fd); + let decodingOptions: image.DecodingOptions = { + editable: true, + desiredPixelFormat: 3, + desiredSize: { width: 400, height: 300 } // When the image resources are large, downsampling should be performed first. + } + imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => { + console.info('Succeeded in creating pixelMap object through image decoding parameters.'); + this.pixel = pixelMap; + }).catch((error: BusinessError) => { + console.error(`Failed to create pixelMap object through image decoding parameters, error.code ${error.code}, error.message ${error.message}`); + }) + }).catch((err: BusinessError) => { + console.error(`Invoke photoPicker.select failed, code is ${err.code}, message is ${err.message}`); + }) + } catch (error) { + let err: BusinessError = error as BusinessError; + console.error('photoPicker failed with err: ' + JSON.stringify(err)); + } + }) + } + .width('100%') + .height('100%') + } + .backgroundColor('#F1F3F5') + } + + // [End DownsampleThePixelmapUsingDesiredSize] +} \ No newline at end of file diff --git a/TextureHypercompression/entry/src/main/ets/pages/Index.ets b/TextureHypercompression/entry/src/main/ets/pages/Index.ets index 140381becc7bf3a672553427963b6a7a666da55c..445a4477ae8628c45c241109deba88a851d3ee24 100644 --- a/TextureHypercompression/entry/src/main/ets/pages/Index.ets +++ b/TextureHypercompression/entry/src/main/ets/pages/Index.ets @@ -1,336 +1,93 @@ /* -* Copyright (c) 2024 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TextureCompression } from './TextureCompression'; +import { OptimizeWebImagesUsingCDN } from './OptimizeWebImagesUsingCDN'; +import { DownsampleThePixelmapUsingDesiredSize } from './DownsampleThePixelmapUsingDesiredSize'; +import { UseAutoResizeToDownsampleTheImageComponent } from './UseAutoResizeToDownsampleTheImageComponent'; @Entry @Component -struct TabsExample { - @State fontColor: string = '#000000'; - @State currentIndex: number = 0; - @State imageWidth: string = '10%'; - @State imageHeight: number = 70; - private controller: TabsController = new TabsController(); +struct Index { + @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack(); @Builder - tabBuilder(index: number, name: string): void { - Column() { - Text(name) - .fontColor(this.currentIndex === index ? Color.White : this.fontColor) - .fontSize(16) - .fontWeight(this.currentIndex === index ? 500 : 400) - .height(40) - .width('100%') - .borderRadius(20) - .textAlign(TextAlign.Center) - .backgroundColor(this.currentIndex === index ? '#0a59f7' : '#f1f3f5') + PageMap(name: string, param: string) { + if (name === 'TextureCompression') { + TextureCompression() + } else if (name === 'OptimizeWebImagesUsingCDN') { + OptimizeWebImagesUsingCDN() + } else if (name === 'DownsampleThePixelmapUsingDesiredSize') { + DownsampleThePixelmapUsingDesiredSize() + } else if (name === 'UseAutoResizeToDownsampleTheImageComponent') { + UseAutoResizeToDownsampleTheImageComponent() } - .width('100%') } build() { - Column() { - Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) { - TabContent() { - Column() + Navigation(this.pageInfos) { + Column() { + Column({ space: 12 }) { + Button('使用纹理压缩优化预置图片') .width('100%') - .height('100%') - .backgroundColor('#F1F3F5') - }.tabBar(this.tabBuilder(0, 'tab1')) - - TabContent() { - Column() { - Row() { - Image($r('app.media.1')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.2')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.3')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.4')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.5')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.6')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.7')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.8')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.9')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.10')) - .width(this.imageWidth) - .height(this.imageHeight) - } - - Row() { - Image($r('app.media.11')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.12')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.13')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.14')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.15')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.16')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.17')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.18')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.19')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.20')) - .width(this.imageWidth) - .height(this.imageHeight) - } - - Row() { - Image($r('app.media.21')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.22')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.23')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.24')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.25')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.26')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.27')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.28')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.29')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.30')) - .width(this.imageWidth) - .height(this.imageHeight) - } - - Row() { - Image($r('app.media.31')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.32')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.33')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.34')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.35')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.36')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.37')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.38')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.39')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.40')) - .width(this.imageWidth) - .height(this.imageHeight) - } + .borderRadius(20) + .backgroundColor('#0A59F7') + .onClick(() => { + this.pageInfos.pushPathByName('TextureCompression', ''); + }) - Row() { - Image($r('app.media.41')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.42')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.43')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.44')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.45')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.46')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.47')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.48')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.49')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.50')) - .width(this.imageWidth) - .height(this.imageHeight) - } - - Row() { - Image($r('app.media.51')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.52')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.53')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.54')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.55')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.56')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.57')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.58')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.59')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.60')) - .width(this.imageWidth) - .height(this.imageHeight) - } + Button('使用CDN优化网络图片资源') + .width('100%') + .borderRadius(20) + .backgroundColor('#0A59F7') + .onClick(() => { + this.pageInfos.pushPathByName('OptimizeWebImagesUsingCDN', ''); + }) - Row() { - Image($r('app.media.61')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.62')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.63')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.64')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.65')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.66')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.67')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.68')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.69')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.70')) - .width(this.imageWidth) - .height(this.imageHeight) - } + Button('使用desiredSize对pixelmap进行降采样') + .width('100%') + .borderRadius(20) + .backgroundColor('#0A59F7') + .onClick(() => { + this.pageInfos.pushPathByName('DownsampleThePixelmapUsingDesiredSize', ''); + }) - Row() { - Image($r('app.media.71')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.72')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.73')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.74')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.75')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.76')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.77')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.78')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.79')) - .width(this.imageWidth) - .height(this.imageHeight) - Image($r('app.media.80')) - .width(this.imageWidth) - .height(this.imageHeight) - } - } - .width('100%') - .height('100%') - .backgroundColor('#F1F3F5') - }.tabBar(this.tabBuilder(1, 'tab2')) + Button('使用autoResize对Image组件进行降采样') + .width('100%') + .borderRadius(20) + .backgroundColor('#0A59F7') + .margin({ bottom: 16 }) + .onClick(() => { + this.pageInfos.pushPathByName('UseAutoResizeToDownsampleTheImageComponent', ''); + }) + } + .width('100%') + .justifyContent(FlexAlign.End) } - .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) - .vertical(false) - .barMode(BarMode.Fixed) - .barWidth(360) - .barHeight(56) - .animationDuration(400) - .onAnimationStart((_index: number, targetIndex: number) => { - this.currentIndex = targetIndex; - }) .width('100%') .height('100%') + .padding({ + left: 16, + right: 16 + }) + .justifyContent(FlexAlign.End) } + .title('图片资源加载优化') + .height('100%') .width('100%') + .backgroundColor('#F1F3F5') + .navDestination(this.PageMap) } } \ No newline at end of file diff --git a/TextureHypercompression/entry/src/main/ets/pages/OptimizeWebImagesUsingCDN.ets b/TextureHypercompression/entry/src/main/ets/pages/OptimizeWebImagesUsingCDN.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c15c533db3ba5b06145029238dc27d58b502dc1 --- /dev/null +++ b/TextureHypercompression/entry/src/main/ets/pages/OptimizeWebImagesUsingCDN.ets @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Component +export struct OptimizeWebImagesUsingCDN { + // [Start OptimizeWebImagesUsingCDN] + // It needs to be replaced with the image resource address required by the developer. + private imgUrl = 'https://******.com/path/to/image.jpg?w=200&h=150&fit=cover&q=85&format=webp'; + + build() { + NavDestination() { + Column() { + Image(this.imgUrl) + .width(200) + .height(150) + .objectFit(ImageFit.Cover) + } + .width('100%') + .height('100%') + } + .backgroundColor('#F1F3F5') + } + // [End OptimizeWebImagesUsingCDN] +} \ No newline at end of file diff --git a/TextureHypercompression/entry/src/main/ets/pages/TextureCompression.ets b/TextureHypercompression/entry/src/main/ets/pages/TextureCompression.ets new file mode 100644 index 0000000000000000000000000000000000000000..1c6da195c6881ad91ac1256e81aefe298795904e --- /dev/null +++ b/TextureHypercompression/entry/src/main/ets/pages/TextureCompression.ets @@ -0,0 +1,335 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +@Component +export struct TextureCompression { + @State fontColor: string = '#000000'; + @State currentIndex: number = 0; + @State imageWidth: string = '10%'; + @State imageHeight: number = 70; + private controller: TabsController = new TabsController(); + + @Builder + tabBuilder(index: number, name: string): void { + Column() { + Text(name) + .fontColor(this.currentIndex === index ? Color.White : this.fontColor) + .fontSize(16) + .fontWeight(this.currentIndex === index ? 500 : 400) + .height(40) + .width('100%') + .borderRadius(20) + .textAlign(TextAlign.Center) + .backgroundColor(this.currentIndex === index ? '#0a59f7' : '#f1f3f5') + } + .width('100%') + } + + build() { + NavDestination() { + Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) { + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor('#F1F3F5') + }.tabBar(this.tabBuilder(0, 'tab1')) + + TabContent() { + Column() { + Row() { + Image($r('app.media.1')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.2')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.3')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.4')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.5')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.6')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.7')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.8')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.9')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.10')) + .width(this.imageWidth) + .height(this.imageHeight) + } + + Row() { + Image($r('app.media.11')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.12')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.13')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.14')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.15')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.16')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.17')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.18')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.19')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.20')) + .width(this.imageWidth) + .height(this.imageHeight) + } + + Row() { + Image($r('app.media.21')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.22')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.23')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.24')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.25')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.26')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.27')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.28')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.29')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.30')) + .width(this.imageWidth) + .height(this.imageHeight) + } + + Row() { + Image($r('app.media.31')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.32')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.33')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.34')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.35')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.36')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.37')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.38')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.39')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.40')) + .width(this.imageWidth) + .height(this.imageHeight) + } + + Row() { + Image($r('app.media.41')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.42')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.43')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.44')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.45')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.46')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.47')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.48')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.49')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.50')) + .width(this.imageWidth) + .height(this.imageHeight) + } + + Row() { + Image($r('app.media.51')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.52')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.53')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.54')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.55')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.56')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.57')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.58')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.59')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.60')) + .width(this.imageWidth) + .height(this.imageHeight) + } + + Row() { + Image($r('app.media.61')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.62')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.63')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.64')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.65')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.66')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.67')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.68')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.69')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.70')) + .width(this.imageWidth) + .height(this.imageHeight) + } + + Row() { + Image($r('app.media.71')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.72')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.73')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.74')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.75')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.76')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.77')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.78')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.79')) + .width(this.imageWidth) + .height(this.imageHeight) + Image($r('app.media.80')) + .width(this.imageWidth) + .height(this.imageHeight) + } + } + .width('100%') + .height('100%') + .backgroundColor('#F1F3F5') + }.tabBar(this.tabBuilder(1, 'tab2')) + } + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + .vertical(false) + .barMode(BarMode.Fixed) + .barWidth(360) + .barHeight(56) + .animationDuration(400) + .onAnimationStart((_index: number, targetIndex: number) => { + this.currentIndex = targetIndex; + }) + .width('100%') + .height('100%') + } + .width('100%') + } +} \ No newline at end of file diff --git a/TextureHypercompression/entry/src/main/ets/pages/UseAutoResizeToDownsampleTheImageComponent.ets b/TextureHypercompression/entry/src/main/ets/pages/UseAutoResizeToDownsampleTheImageComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..6ff11dff6b80e1d14421dcc5d6065bf84ef47f72 --- /dev/null +++ b/TextureHypercompression/entry/src/main/ets/pages/UseAutoResizeToDownsampleTheImageComponent.ets @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BusinessError } from "@kit.BasicServicesKit"; +import { image } from "@kit.ImageKit"; +import { fileIo } from "@kit.CoreFileKit"; +import { photoAccessHelper } from "@kit.MediaLibraryKit"; + +@Component +export struct UseAutoResizeToDownsampleTheImageComponent { + @State imageUrl: image.PixelMap | undefined = undefined; + + build() { + NavDestination() { + Column() { + // [Start UseAutoResizeToDownsampleTheImageComponent] + Image(this.imageUrl) + .width(300) + .height(200) + .autoResize(true) + // [End UseAutoResizeToDownsampleTheImageComponent] + + Button('Select image').onClick(() => { + try { + // Select album images. + let uris: Array = []; + let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); + PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; + PhotoSelectOptions.maxSelectNumber = 1; + let photoPicker = new photoAccessHelper.PhotoViewPicker(); + photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => { + uris = PhotoSelectResult.photoUris; + let file = fileIo.openSync(uris[0], fileIo.OpenMode.READ_ONLY); + console.info('file fd: ' + file.fd); + let buffer = new ArrayBuffer(4096); + let readLen = fileIo.readSync(file.fd, buffer); + console.info('readSync data to file succeed and buffer size is:' + readLen); + const imageSource: image.ImageSource = image.createImageSource(file.fd); + let decodingOptions: image.DecodingOptions = { + editable: true, + desiredPixelFormat: 3 + } + imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => { + console.info('Succeeded in creating pixelMap object through image decoding parameters.'); + this.imageUrl = pixelMap; + }).catch((error: BusinessError) => { + console.error(`Failed to create pixelMap object through image decoding parameters, error.code ${error.code}, error.message ${error.message}`); + }) + }).catch((err: BusinessError) => { + console.error(`Invoke photoPicker.select failed, code is ${err.code}, message is ${err.message}`); + }) + } catch (error) { + let err: BusinessError = error as BusinessError; + console.error('photoPicker failed with err: ' + JSON.stringify(err)); + } + }) + } + .width('100%') + .height('100%') + } + .backgroundColor('#F1F3F5') + } +} \ No newline at end of file diff --git a/TextureHypercompression/screenshots/device/effect.png b/TextureHypercompression/screenshots/device/effect.png new file mode 100644 index 0000000000000000000000000000000000000000..8d8a794cbf3c31d44627fd33c6d7c40e0c6f8aad Binary files /dev/null and b/TextureHypercompression/screenshots/device/effect.png differ