人工智能

鸿蒙基于图像模块实现图库图片的四种常见操作开发分享

时间:2010-12-5 17:23:32  作者:应用开发   来源:IT科技类资讯  查看:  评论:0
内容摘要:想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com1. 项目介绍HarmonyOS图像模块支持图像业务的开发,常见功能如图像解码、图像编码、

想了解更多内容,鸿蒙请访问:

和华为官方合作共建的基于鸿蒙技术社区

https://harmonyos.51cto.com

1. 项目介绍

HarmonyOS图像模块支持图像业务的开发,常见功能如图像解码、图像图库图片图像编码、模块基本的实现位图操作、图像编辑等。常见操作当然,分享也支持通过接口组合来实现更复杂的鸿蒙图像处理逻辑。本教程以图库图片中旋转、基于剪裁、图像图库图片缩放、模块镜像四种常见操作为例,实现给大家介绍HarmonyOS图像编解码的常见操作相关开发指导。

2. 将图片转换为PixelMap

图像解码就是分享将所支持格式的存档图片解码成统一的PixelMap图像,用于后续图像显示或其他处理,鸿蒙比如旋转、缩放、高防服务器剪裁等。当前支持格式包括JPEG、PNG、GIF、HEIF、WebP、BMP。本例为您提供了getPixelMapFromResource函数,可以将resources/base/media目录下的图片资源转换为PixelMap图像,其中入参为图片的资源ID。

private PixelMap getPixelMapFromResource(int resourceId) {      InputStream inputStream = null;     try {          // 创建图像数据源ImageSource对象         inputStream = getContext().getResourceManager().getResource(resourceId);         ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();         srcOpts.formatHint = "image/jpg";         ImageSource imageSource = ImageSource.create(inputStream, srcOpts);         // 设置图片参数         ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();         return imageSource.createPixelmap(decodingOptions);     } catch (IOException e) {          HiLog.info(LABEL_LOG, "IOException");     } catch (NotExistException e) {          HiLog.info(LABEL_LOG, "NotExistException");     } finally {          if (inputStream != null) {              try {                  inputStream.close();             } catch (IOException e) {                  HiLog.info(LABEL_LOG, "inputStream IOException");             }         }     }     return null; } 

3. 图片参数设置

本例使用图片像素的尺寸为1024*768,点击一次旋转按钮会进行90度的旋转,缩放是按照2:1的比例进行缩放,剪裁是保证宽度不变的情况下对高度进行400像素的剪裁,相关参数设置如下所示:

// 设置图片参数  ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();  // 旋转  decodingOptions.rotateDegrees = 90 * whirlCount;  // 缩放  decodingOptions.desiredSize = new Size(isScale ? 512 : 0, isScale ? 384 : 0);  // 剪裁  decodingOptions.desiredRegion = new Rect(0, 0, isCorp ? 1024 : 0, isCorp ? 400 : 0); 

4. 图片镜像操作

图片镜像操作就是网站模板对图片以纵坐标为轴制作对称图片。image绘制的时候会调用onDraw方法,本例采用对图像Canvas画布的镜像操作实现图片的镜像显示,示例代码如下所示:

private void mirrorImage(PixelMap pixelMap) {       scaleX = -scaleX;      image.addDrawTask(              new Component.DrawTask() {                   @Override                  public void onDraw(Component component, Canvas canvas) {                       if (isMirror) {                           isMirror = false;                          PixelMapHolder pmh = new PixelMapHolder(pixelMap);                          canvas.scale(                                  scaleX,                                  1.0f,                                  (float) pixelMap.getImageInfo().size.width / 2,                                  (float) pixelMap.getImageInfo().size.height / 2);                          canvas.drawPixelMapHolder(                                  pmh,                                  0,                                  0,                                  new Paint());                      }                  }              });  } 

5. 完整示例

以手机为例,初始化页面如图1所示,依次点击按钮可以实现图片的旋转、剪裁、缩放、镜像,效果如下所示(您需要准备一张像素尺寸为1024*768的图片,放到ImageDemo\entry\src\main\resources\base\media目录下):

示例代码如下:

import com.huawei.codelab.ResourceTable;  import ohos.aafwk.ability.AbilitySlice;  import ohos.aafwk.content.Intent;  import ohos.agp.components.Button;  import ohos.agp.components.Component;  import ohos.agp.components.Image;  import ohos.agp.render.Canvas;  import ohos.agp.render.Paint;  import ohos.agp.render.PixelMapHolder;  import ohos.global.resource.NotExistException;  import ohos.hiviewdfx.HiLog;  import ohos.hiviewdfx.HiLogLabel;  import ohos.media.image.ImageSource;  import ohos.media.image.PixelMap;  import ohos.media.image.common.PixelFormat;  import ohos.media.image.common.Rect;  import ohos.media.image.common.Size;  import java.io.IOException;  import java.io.InputStream;  /**   * 图像主页面   */  public class MainAbilitySlice extends AbilitySlice {       private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "MainAbilitySlice");      Image image;      PixelMap imagePixelMap;      Button whirlImageBtn;      Button cropImageBtn;      Button scaleImageBtn;      Button mirrorImageBtn;      private int whirlCount = 0;      private boolean isCorp = false;      private boolean isScale = false;      private boolean isMirror = false;      private float scaleX = 1.0f;      @Override      public void onStart(Intent intent) {           super.onStart(intent);          super.setUIContent(ResourceTable.Layout_ability_main);          initView();      }      private void initView() {           if (findComponentById(ResourceTable.Id_whirl_image) instanceof Button) {               whirlImageBtn = (Button) findComponentById(ResourceTable.Id_whirl_image);          }          if (findComponentById(ResourceTable.Id_crop_image) instanceof Button) {               cropImageBtn = (Button) findComponentById(ResourceTable.Id_crop_image);          }          if (findComponentById(ResourceTable.Id_scale_image) instanceof Button) {               scaleImageBtn = (Button) findComponentById(ResourceTable.Id_scale_image);          }          if (findComponentById(ResourceTable.Id_mirror_image) instanceof Button) {               mirrorImageBtn = (Button) findComponentById(ResourceTable.Id_mirror_image);          }          if (findComponentById(ResourceTable.Id_image) instanceof Image) {               image = (Image) findComponentById(ResourceTable.Id_image);          }          whirlImageBtn.setClickedListener(new ButtonClick());          cropImageBtn.setClickedListener(new ButtonClick());          scaleImageBtn.setClickedListener(new ButtonClick());          mirrorImageBtn.setClickedListener(new ButtonClick());      }      private class ButtonClick implements Component.ClickedListener {           @Override          public void onClick(Component component) {               int btnId = component.getId();              switch (btnId) {                   case ResourceTable.Id_whirl_image:                      // 旋转图片                      whirlCount++;                      isCorp = false;                      isScale = false;                      isMirror = false;                      imagePixelMap = getPixelMapFromResource(ResourceTable.Media_shanghai);                      image.setPixelMap(imagePixelMap);                      break;                  case ResourceTable.Id_crop_image:                      // 剪裁图片                      whirlCount = 0;                      isCorp = !isCorp;                      isScale = false;                      isMirror = false;                      imagePixelMap = getPixelMapFromResource(ResourceTable.Media_shanghai);                      image.setPixelMap(imagePixelMap);                      break;                  case ResourceTable.Id_scale_image:                      // 缩放图片                      whirlCount = 0;                      isCorp = false;                      isScale = !isScale;                      isMirror = false;                      imagePixelMap = getPixelMapFromResource(ResourceTable.Media_shanghai);                      image.setPixelMap(imagePixelMap);                      break;                  case ResourceTable.Id_mirror_image:                      // 镜像图片                      whirlCount = 0;                      isCorp = false;                      isScale = false;                      isMirror = true;                      imagePixelMap = getPixelMapFromResource(ResourceTable.Media_shanghai);                      mirrorImage(imagePixelMap);                      image.setPixelMap(imagePixelMap);                      break;                  default:                      break;              }          }      }      private void mirrorImage(PixelMap pixelMap) {           scaleX = -scaleX;          image.addDrawTask(                  new Component.DrawTask() {                       @Override                      public void onDraw(Component component, Canvas canvas) {                           if (isMirror) {                               isMirror = false;                              PixelMapHolder pmh = new PixelMapHolder(pixelMap);                              canvas.scale(                                      scaleX,                                      1.0f,                                      (float) pixelMap.getImageInfo().size.width / 2,                                      (float) pixelMap.getImageInfo().size.height / 2);                              canvas.drawPixelMapHolder(                                      pmh,                                      0,                                      0,                                      new Paint());                          }                      }                  });      }      /**       * 通过图片ID返回PixelMap       *       * @param resourceId 图片的资源ID       * @return 图片的PixelMap       */      private PixelMap getPixelMapFromResource(int resourceId) {           InputStream inputStream = null;          try {               // 创建图像数据源ImageSource对象              inputStream = getContext().getResourceManager().getResource(resourceId);              ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();              srcOpts.formatHint = "image/jpg";              ImageSource imageSource = ImageSource.create(inputStream, srcOpts);              // 设置图片参数              ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();              // 旋转              decodingOptions.rotateDegrees = 90 * whirlCount;              // 缩放              decodingOptions.desiredSize = new Size(isScale ? 512 : 0, isScale ? 384 : 0);              // 剪裁              decodingOptions.desiredRegion = new Rect(0, 0, isCorp ? 1024 : 0, isCorp ? 400 : 0);              decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;              return imageSource.createPixelmap(decodingOptions);          } catch (IOException e) {               HiLog.info(LABEL_LOG, "IOException");          } catch (NotExistException e) {               HiLog.info(LABEL_LOG, "NotExistException");          } finally {               if (inputStream != null) {                   try {                       inputStream.close();                  } catch (IOException e) {                       HiLog.info(LABEL_LOG, "inputStream IOException");                  }              }          }          return null;      }      @Override      public void onActive() {           super.onActive();      }      @Override      public void onForeground(Intent intent) {           super.onForeground(intent);      }  }  

布局代码如下:

<?xml version="1.0" encoding="utf-8"?>  <DirectionalLayout      xmlns:ohos="http://schemas.huawei.com/res/ohos"      ohos:height="match_parent"      ohos:width="match_parent"      ohos:orientation="vertical">      <Text          ohos:height="match_content"          ohos:width="match_content"          ohos:layout_alignment="horizontal_center"          ohos:text="HarmonyOS图像开发"          ohos:text_size="80"          ohos:top_margin="40vp"          />      <DirectionalLayout          xmlns:ohos="http://schemas.huawei.com/res/ohos"          ohos:height="match_content"          ohos:width="match_content"          ohos:layout_alignment="horizontal_center"          ohos:orientation="horizontal"          ohos:top_margin="20vp">          <Button              ohos:id="$+id:whirl_image"              ohos:height="match_content"              ohos:width="match_content"              ohos:background_element="$graphic:background_button"              ohos:padding="12vp"              ohos:right_margin="5vp"              ohos:text="旋转"              ohos:text_size="20vp"              ohos:top_margin="10vp">          </Button>          <Button              ohos:id="$+id:crop_image"              ohos:height="match_content"              ohos:width="match_content"              ohos:background_element="$graphic:background_button"              ohos:left_margin="5vp"              ohos:padding="12vp"              ohos:text="剪裁"              ohos:text_size="20vp"              ohos:top_margin="10vp">          </Button>          <Button              ohos:id="$+id:scale_image"              ohos:height="match_content"              ohos:width="match_content"              ohos:background_element="$graphic:background_button"              ohos:left_margin="5vp"              ohos:padding="12vp"              ohos:text="缩放"              ohos:text_size="20vp"              ohos:top_margin="10vp">          </Button>          <Button              ohos:id="$+id:mirror_image"              ohos:height="match_content"              ohos:width="match_content"              ohos:background_element="$graphic:background_button"              ohos:left_margin="5vp"              ohos:padding="12vp"              ohos:text="镜像"              ohos:text_size="20vp"              ohos:top_margin="10vp"/>      </DirectionalLayout>      <Image          ohos:id="$+id:image"          ohos:height="match_content"          ohos:width="match_content"          ohos:image_src="$media:shanghai.jpg"          ohos:layout_alignment="horizontal_center"          ohos:top_margin="20vp">      </Image>  </DirectionalLayout> 

此外您还需在resource/base/graphic目录下添加background_button.xml

<?xml version="1.0" encoding="utf-8"?>  <shape xmlns:ohos="http://schemas.huawei.com/res/ohos"         ohos:shape="rectangle">      <corners          ohos:radius="40"/>      <solid          ohos:color="#e9e9e9"/>  </shape> 

说明

以上代码仅demo演示参考使用,产品化的代码需要考虑数据校验和国际化。

想了解更多内容,请访问:

和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

copyright © 2025 powered by 益强资讯全景  滇ICP备2023006006号-31sitemap