看看天空 发表于 2021-4-23 17:08

【图片旋转】HarmonyOS Codelab挑战赛记录

# 图片旋转

## 项目启动

![%E5%9B%BE%E7%89%87%E6%97%8B%E8%BD%AC%20cae6676994e6424590cab9c1d4624e21/Untitled.png](https://i.loli.net/2021/04/22/MoSdes5IfcB268G.png)

## 布局文件

在resource/base/layout 目录下修改 ability_main.xml

```xml
<?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.png"
      ohos:layout_alignment="horizontal_center"
      ohos:top_margin="20vp">
    </Image>

</DirectionalLayout>
```

![%E5%9B%BE%E7%89%87%E6%97%8B%E8%BD%AC%20cae6676994e6424590cab9c1d4624e21/Untitled%201.png](https://i.loli.net/2021/04/22/QOdJUMopcma2q1C.png)

在resource/base/graphic目录下添加background_button.xml

```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>
```

## slice 目录

在src/main/java/com/example/pictureoperation/slice目录下(不同的项目名称不同,官网例子为com/huawei/codelab)修改 MainAbilitySlice.java文件,继承AbilitySlice。
定义成员变量

![%E5%9B%BE%E7%89%87%E6%97%8B%E8%BD%AC%20cae6676994e6424590cab9c1d4624e21/Untitled%202.png](https://i.loli.net/2021/04/22/ulAZYnwdUWLPVCx.png)

类名和包名对应你的项目名,复制过来的项目代码需要对应修改

MainAbilitySlice.java

```java
package com.example.pictureoperation.slice;

import com.example.pictureoperation.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);
    }
}
```

![%E5%9B%BE%E7%89%87%E6%97%8B%E8%BD%AC%20cae6676994e6424590cab9c1d4624e21/Untitled%203.png](https://i.loli.net/2021/04/22/hz7l6TWnmGSLZJe.png)

这里的 Media_shanghai 对应

![%E5%9B%BE%E7%89%87%E6%97%8B%E8%BD%AC%20cae6676994e6424590cab9c1d4624e21/Untitled%204.png](https://i.loli.net/2021/04/22/a9YqRlNswgTEZ57.png)

最后导入一张 1024 * 768 的图片

![%E5%9B%BE%E7%89%87%E6%97%8B%E8%BD%AC%20cae6676994e6424590cab9c1d4624e21/shanghai.png](https://i.loli.net/2021/04/22/JercD7WtPUCyNik.png)

## 效果展示

![%E5%9B%BE%E7%89%87%E6%97%8B%E8%BD%AC%20cae6676994e6424590cab9c1d4624e21/PictureOperation.gif](https://i.loli.net/2021/04/22/hl8X5DiCeJKGcFU.gif)

夏520 发表于 2021-4-23 17:36

正好我的手机正好是P40PRO,能用

logafo 发表于 2021-4-23 17:36

谢谢楼主!!参考一下!!
页: [1]
查看完整版本: 【图片旋转】HarmonyOS Codelab挑战赛记录