首页 > 其他分享 >九宫格切图-创意分享新风尚

九宫格切图-创意分享新风尚

时间:2024-10-18 13:21:36浏览次数:4  
标签:新风尚 切图 九宫格 图库 width let await 图片

作者:狼哥
团队:坚果派
团队介绍:坚果派由坚果等人创建,团队拥有12个华为HDE带领热爱HarmonyOS/OpenHarmony的开发者,以及若干其他领域的三十余位万粉博主运营。专注于分享HarmonyOS/OpenHarmony、ArkUI-X、元服务、仓颉。团队成员聚集在北京,上海,南京,深圳,广州,宁夏等地,目前已开发鸿蒙原生应用,三方库60+,欢迎交流。

介绍

​ 在社交媒体日益繁荣的今天,九宫格切图以其独特的视觉呈现方式,成为了朋友圈中的一股清新之风。通过将一张完整图片精心切割为九个小方块,再依次排列发布,不仅让图片内容更加层次分明,还能激发观者的探索欲,引导他们逐格浏览,享受发现新细节的乐趣。

​ 九宫格图片的用处广泛而巧妙。它适用于旅行美景的展示,每一格都是一处风景的缩影,串联起一段完整的旅程记忆;也是美食分享的绝佳选择,从食材准备到成品呈现,步步精彩,让人垂涎欲滴;更可用于生活日常的创意记录,无论是温馨的家庭瞬间,还是个人的小确幸,都能在九宫格的框架下,被赋予更多故事性和观赏性。这种创意切图方式,让每一次分享都变得更加有趣和生动,是连接你我,传递美好情感的新桥梁。

效果预览

工程目录

├──entry/src/main/ets                         // 代码区
│  ├──dialog
│  │  └──ImagePicker.ets                      // 图片选择
│  ├──entryability
│  │  └──EntryAbility.ets 
│  ├──model
│  │  ├──ImageModel.ets                       // 图片操作
│  │  └──PictureItem.ets                      // 图片对象
│  └──pages
│     └──Index.ets                            // 首页
└──entry/src/main/resources                   // 应用资源目录

具体实现

1. 权限添加

配置文件module.json5里添加读取图片及视频权限和修改图片或视频权限。

"requestPermissions": [
      {
        "name": "ohos.permission.WRITE_MEDIA",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        },
        "reason": "$string:WRITE_MEDIA"
      },
      {
        "name": "ohos.permission.MEDIA_LOCATION",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        },
        "reason": "$string:MEDIA_LOCATION"
      },
      {
        "name": "ohos.permission.READ_IMAGEVIDEO",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        },
        "reason": "$string:READ_IMAGEVIDEO"
      },
      {
        "name": "ohos.permission.WRITE_IMAGEVIDEO",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        },
        "reason": "$string:WRITE_IMAGEVIDEO"
      }
    ]
2. 图片选择对话

获取本地图片:首先使用getPhotoAccessHelper获取相册管理模块实例,然后使用getAssets方法获取文件资源,最后使用getAllObjects获取检索结果中的所有文件资产方便展示;

	let photoList: Array<photoAccessHelper.PhotoAsset> = [];
  
    let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
    let fetchOptions: photoAccessHelper.FetchOptions = {
      fetchColumns: [],
      predicates: predicates
    }

    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await this.phAccessHelper.getAssets(fetchOptions);
    if (fetchResult != undefined) {
      let photoAsset: Array<photoAccessHelper.PhotoAsset> = await fetchResult.getAllObjects();
      if (photoAsset != undefined && photoAsset.length > 0) {
        for (let i = 0; i < photoAsset.length; i++) {
          if (photoAsset[i].photoType === 1) {
            photoList.push(photoAsset[i]);
          }
        }
      }
    }

自定义对话框显示获取到的本地图片

import { photoAccessHelper } from '@kit.MediaLibraryKit';

@CustomDialog
export struct ImagePicker {
  @Link index: number;
  private imagesData: Array<photoAccessHelper.PhotoAsset> = [];
  public controller: CustomDialogController;
  @State selected: number = 0;

  build() {
    Column() {
      List({ space: 5 }) {
        ForEach(this.imagesData, (item: photoAccessHelper.PhotoAsset, index) => {
          ListItem() {
            Stack({ alignContent: Alignment.TopEnd }) {...}
        }, (item: photoAccessHelper.PhotoAsset) => JSON.stringify(item))
      }
      .width('95%')
      .height(160)
      .listDirection(Axis.Horizontal)

      Row() {...}
      .margin({ bottom: 10, top: 10 })
    }
    .width('100%')
    .padding({ top: 16, left: 16, right: 16 })
  }
}
3. 切图九宫格

使用createImagePacker创建ImagePacker实例,然后使用fs.open打开文件,调用createImageSource接口创建图片源实例方便操作图片,接下来使用getImageInfo方法获取图片大小便于分割,最后使用createPixelMap方法传入每一份的尺寸参数完成图片裁剪。具体就是根据图片选择对话框,选择的下标,到图库里获取到选择的图片,然后以只读方式打开图片,获取打开图片信息,计算出切图后的宽度和高度,根据参数生成新切图,并缓存到数组里,方便显示切图后的九宫格,最后调用存储函数把切图存储到图库里,方便之后使用,比如发朋友图。

async splitPic(index: number): Promise<Array<PictureItem>> {
    // 调用上面函数获取全部图片
    let imagesData: Array<photoAccessHelper.PhotoAsset> = await this.getAllImg();
    console.info(`xx testTag splitPic 图库图片数量为: ${imagesData.length}`)
    let imagePixelMap: Array<PictureItem> = [];
    // 创建图像编码ImagePacker对象
    let imagePickerApi = image.createImagePacker();

    // 以只读方式打开指定下标图片
    await fileIo.open(imagesData[index].uri, fileIo.OpenMode.READ_ONLY).then(async (file: fileIo.File) => {
      let fd: number = file.fd;
      // 获取图片源
      let imageSource = image.createImageSource(fd);
      // 图片信息
      let imageInfo = await imageSource.getImageInfo();
      // 图片高度除以3,就是把图片切为3份
      let height = imageInfo.size.height / this.splitCount;
      let width = imageInfo.size.width / this.splitCount;
      // 切换为 3x3 张图片
      for (let i = 0; i < this.splitCount; i++) {
        for (let j = 0; j < this.splitCount; j++) {
          // 设置解码参数DecodingOptions,解码获取pixelMap图片对象
          let decodingOptions: image.DecodingOptions = {
            desiredRegion: {
              size: {
                height: height, // 切开图片高度
                width: width  // 切开图片宽度
              },
              x: j * width,   // 切开x起始位置
              y: i * height     // 切开y起始位置
            }
          }
          // 根据参数重新九宫格图片
          let img: image.PixelMap = await imageSource.createPixelMap(decodingOptions);
          // 把生成新图片放到内存里
          imagePixelMap.push(new PictureItem(i * this.splitCount + j, img));
          // 保存到相册
          await this.savePixelMap(img)
        }
      }

      imagePickerApi.release();
      fileIo.closeSync(fd);
    })

    return imagePixelMap;
  }
4. 保存图库

把上面切出来的PixelMap先转为ArrayBuffer,然后通过PhotoAccessHelper模块提供相册管理模块能力,包括创建相册以及访问、修改相册中的媒体数据信息等。把ArrayBuffer保存到图库里。

async savePixelMap(pm: PixelMap) {
    if (this.phAccessHelper === null) {
      return;
    }
    const imagePackerApi: image.ImagePacker = image.createImagePacker();
    const packOpts: image.PackingOption = { format: 'image/jpeg', quality: 30 };
    try {
      const buffer: ArrayBuffer = await imagePackerApi.packing(pm, packOpts);
      let options: photoAccessHelper.CreateOptions = {
        title: new Date().getTime().toString()
      };

      let photoUri: string = await this.phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg', options);
      let file: fileIo.File = fileIo.openSync(photoUri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
      await fileIo.write(file.fd, buffer);
      fileIo.closeSync(file);
    } catch (err) {
      console.error(err)
    }
  }
5. 界面布局

顶部和底部显示红色说明文字,上面默认显示图库第一张图上,点击图片弹出对话框选择图库里的其它图片,下来是个切割九宫格按钮,点击可以把选择的图片切割为九张图片,并自动保存到图库里。

Column() {
      Text(`默认显示图库第一张图片、点击图片弹出图库对话框、选择一张希望切九宫格图片!`)
        .fontSize(10)
        .fontColor(Color.Red)
      Image(this.imgData[this.index]?.uri)
        .objectFit(ImageFit.Contain)
        .width('100%')
        .aspectRatio(1)
        .margin(20)
        .onClick(async () => {
          this.imagePixelMap = [];
          this.imgData = await this.imageModel.getAllImg();
          setTimeout(() => {
            this.dialogController.open();
          }, 200);
        })

      Stack() {
        Divider()
          .width('100%')
          .color(Color.Orange)
        Button('切割九宫格')
          .onClick(async () => {
            this.imagePixelMap = [];
            this.imagePixelMap = await this.imageModel.splitPic(this.index);
          })
      }
      .width('100%')
      .height(30)

      Grid() {
        ForEach(this.imagePixelMap, (item: PictureItem, index:number) => {
          GridItem() {
            Image(item.pixelMap)
              .width('99%')
              .objectFit(ImageFit.Fill)
              .height(90)
          }
          .backgroundColor(item.pixelMap === undefined ? '#f5f5f5' : '#ffdead')
        }, (item: PictureItem) => JSON.stringify(item))
      }
      .columnsTemplate('1fr 1fr 1fr')
      .columnsGap(2)
      .rowsGap(2)
      .backgroundColor('#fff')
      .width('100%')
      .aspectRatio(1)
      .margin(20)
      .layoutWeight(1)

      Text(`上面九宫格图片已保存到图库、请移步到图库发一个不一样的朋友圈吧!`)
        .fontSize(10)
        .fontColor(Color.Red)
    }
    .height('100%')
    .width('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Start)
6. 权限申请

在页面生命周期aboutToAppear函数时,调用权限申请,并获取图库数据。

const PERMISSIONS: Array<Permissions> = [
  'ohos.permission.READ_MEDIA',
  'ohos.permission.WRITE_MEDIA',
  'ohos.permission.MEDIA_LOCATION',
  'ohos.permission.MANAGE_MISSIONS'
];
async aboutToAppear() {
    await abilityAccessCtrl.createAtManager().requestPermissionsFromUser(getContext(this), PERMISSIONS);
    this.imgData = await this.imageModel.getAllImg();
  }

相关权限

读取图片及视频权限:ohos.permission.READ_IMAGEVIDEO

修改图片或视频权限:ohos.permission.WRITE_IMAGEVIDEO

约束与限制

1.本示例仅支持标准系统上运行,支持设备:华为手机。

2.HarmonyOS系统:HarmonyOS NEXT Developer Beta1及以上。

3.DevEco Studio版本:DevEco Studio NEXT Developer Beta1及以上。

4.HarmonyOS SDK版本:HarmonyOS NEXT Developer Beta1 SDK及以上。

标签:新风尚,切图,九宫格,图库,width,let,await,图片
From: https://www.cnblogs.com/army16/p/18474058

相关文章

  • 嘉林文化传媒(绍兴)有限公司是一家出品公司曾出品过《盛夏里的旧时光》...嘉林娱乐引领
    嘉林文化传媒(绍兴)有限公司出品的影视剧《盛夏里的旧时光》是一部备受期待的作品。这部剧以其深刻的情感和引人入胜的剧情,讲述了年幼时不幸失去双亲的林屿嘉展开,他在冰冷的亲戚家中度过了十个春秋。十六岁那年,林屿嘉的生活因转学到许肆家附近而发生转折,两个少年由此建立起深厚的友谊......
  • 九宫格(html css实现)---初识flex布局
    记录flex属性并实现一个九宫格flex属性Flex容器:需要注意的是:当时设置flex布局之后,子元素的float、clear、vertical-align的属性将会失效.container{display:flex;}//块状元素.container{inline-flex;}//行内元素块状元素1.***独占一行:块元素会自动......
  • 科技改变生活,IsMyLcdOK引领屏幕检测新风尚
    科技之光,照亮繁忙的日常,让信息流通无阻,决策瞬间达成,助力我们在快节奏中精准协调,共创辉煌——而屏幕作为我们与数字世界交互的窗口,其质量直接关系到我们的使用体验。然而,随着液晶显示器的普及,屏幕坏点问题逐渐成为困扰我们的一大难题。为了应对这一问题,一款名为“IsMyLcdOK”的......
  • 哥伦比亚TV:重塑影视体验,引领未来娱乐新风尚
    在瞬息万变的数字时代,影视娱乐行业正经历着前所未有的变革。作为行业内的创新先锋,哥伦比亚TV凭借其敏锐的洞察力、深厚的技术底蕴以及对用户需求的深刻理解,正逐步重塑影视体验,引领未来娱乐新风尚。在技术的浪潮中,哥伦比亚TV始终站在前沿,不断探索和应用新技术,以驱动影视体验......
  • L1-104 九宫格 分数 20
    #include<bits/stdc++.h>usingnamespacestd;intarr[10][10];intmain(){intn;cin>>n;for(intt=1;t<=n;++t){for(intj=1;j<=9;++j)for(intk=1;k<=9;++k) cin......
  • 汽车资讯一:新能源汽车市场迎来爆发式增长,绿色出行成新风尚!
    随着全球对环境保护意识的日益增强以及科技的飞速发展,新能源汽车市场正以前所未有的速度扩张,成为汽车行业的新宠儿。据最新市场研究报告显示,今年第一季度,全球新能源汽车销量同比大幅增长,多个国家和地区的新能源汽车渗透率创下历史新高,绿色出行正逐渐成为人们的新风尚。技术创......
  • OpenCV图像处理——按最小外接矩形剪切图像
    引言在图像处理过程中,提取感兴趣区域(ROI)并在其上进行处理后,往往需要将处理后的结果映射回原图像。这一步通常涉及以下几个步骤:找到最小外接矩形:使用cv::boundingRect或cv::minAreaRect提取感兴趣区域的最小外接矩形。从原图中提取ROI:根据矩形坐标从原图中剪切出RO......
  • 前端开发工程师简历焕新服务 —— 定制专属魅力,引领职场新风尚
    手机或电脑浏览器就可以打开,面霸宝典【全拼音】.com这里可以优化简历,模拟面试,企业项目源码,最新最全大厂高并发面试题,项目场景题,算法题,底层原理题在前端技术的浪潮中,每一位开发工程师都是引领潮流的先锋。但如何在众多求职者中脱颖而出,让招聘者一眼相中?答案在于一份精心......
  • 基于JSP的九宫格日志网站
    你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。开发语言:Java数据库:MySQL技术:JSP+JavaBeans+Servlet工具:Eclipse、Navicat、Maven系统展示首页管理员功能模块用户功能模块论坛管理摘要本文详细介绍了基于JSP技术的九宫格日志网站,该系统以B/S结......
  • 【全网独家】java 九宫格拼图游戏(代码+测试部署)
    介绍九宫格拼图是一种经典的益智游戏,玩家需要将一幅图像打乱并重新排列,从而恢复原图。游戏通常以一个3x3的网格形式展现,每个方块包含图片的一部分。应用使用场景教育:帮助提高儿童的逻辑思维能力和动手能力。娱乐:提供消遣和挑战,适用于所有年龄段的玩家。认知训练......