想了解更多内容,鸿蒙鸿蒙请访问:
和华为官方合作共建的模式鸿蒙技术社区
https://harmonyos.51cto.com
1. 鸿蒙版图片裁剪功能,效果如下:
首页
图片裁剪区域:
裁剪结果:
2.Java代码实现如下:
package com.example.javahm9.slice; import com.example.javahm9.ResourceTable; import com.example.javahm9.util.CropImage; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.colors.RgbColor; import ohos.agp.components.Button; import ohos.agp.components.Component; import ohos.agp.components.Text; import ohos.agp.components.element.ShapeElement; public class MainAbilitySlice extends AbilitySlice { //定义一个图片 Component image; //定义一个文本 Text text; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main); //获取图片对象对应的图片component image = findComponentById(ResourceTable.Id_result_image); /* * 如果接收的cropFlag为true * 处理剪裁后的图片 * 否则跳过 */ if(intent.getBooleanParam("cropFlag",false)){ handleCrop(intent); } /* 自定义--获取文本对象对应的component * 根据intent里面的cropStatus来显示不同的文本 * 0表示未接收到数据 * 1表示剪裁取消 * 2表示剪裁成功 有数据 */ text = (Text) findComponentById(ResourceTable.Id_text); if(intent.getIntParam("cropStatus",0) == 0){ text.setText("欢迎使用"); }else if(intent.getIntParam("cropStatus",0) == 1){ text.setText("剪裁取消"); }else if(intent.getIntParam("cropStatus",0) == 2){ text.setText("剪裁成功"); } //获取button对象对应的component Button button = (Button) findComponentById(ResourceTable.Id_button); // 设置button的属性及背景 ShapeElement background = new ShapeElement(); // background.setRgbColor(new RgbColor(125, 125, 255)); background.setCornerRadius(25); // button.setBackground(background); if (button != null) { // 绑定点击事件 button.setClickedListener(new Component.ClickedListener() { public void onClick(Component v) { begincrop(); } }); } } public void begincrop(){ CropImage.activity() .setContext(this) .setSource(ResourceTable.Media_a9) .setBundleName("com.example.javahm9") .setAbilityName("com.example.javahm9.MainAbility") .setRequset_code(1234) .start(super.getAbility(),this); } //处理剪裁结果 private void handleCrop(Intent result) { int resultImg = result.getIntParam("resultImg",0); int result_code = result.getIntParam("result_code" , 0); if(resultImg != 0){ CropImage.handleImage(result_code , image); } } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }3.裁剪工具类实现
package com.example.javahm9.util; import ohos.aafwk.ability.Ability; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.Component; import ohos.agp.render.Canvas; import ohos.agp.render.Paint; import ohos.agp.render.PixelMapHolder; import ohos.app.Context; import ohos.media.image.PixelMap; import ohos.utils.net.Uri; /** * @Author 李欣 * <p> * 此类是一个工具类 * <p> * 此类是面向于用户的 面向于MainAbilitySlice的 * <p> * 此类提供设置一些参数的功能,提供了页面跳转,裁剪跳转到CropImageActivity的鸿蒙鸿蒙方法,有一些属性暂时用不到。模式 */ public final class CropImage { //存一个context private static Context mContext; //图片资源文件 private static int msource; //裁减结果 public static final boolean CROPFLAG = true; //空的图片构造器 private CropImage() { } //内部类初始化 public static ActivityBuilder activity() { return new ActivityBuilder(null , null , null , 0); } /** * 这个方法对传进来的 component进行操作 * 给这个空的component增加图片 旋转等等 * @param result 一个参数用来判断返回的结果 以及如何处理 * @param component 对这个component进行操作 */ public static void handleImage(int result, Component component) { //203表示裁剪成功(203为自定义的数字) if (result == 203) { //获得原始位图 PixelMap pixelMap = BitmapUtils.getOriginalPixelMap(mContext , msource).get(); //创建屏幕工具类 获得屏幕的宽度 CropWindowHandler windowHandler = new CropWindowHandler(mContext); /** * 缩放指数 原始的图片的云服务器缩放大小 * 数值为原始图片的宽度(pixelMap.getImageInfo().size.width)除以屏幕的宽度(windowHandler.getWindowWidth()) 的倒数 */ float ratio = (float) windowHandler.getWindowWidth()/(float) pixelMap.getImageInfo().size.width; //获得裁剪后的位图 PixelMap cropped = CropOverlayView.getCroppedPixelMap(); PixelMapHolder pixelMapHolder = new PixelMapHolder(cropped); //创建bitmaputils工具类,获得位图相关数据 BitmapUtils bitmapUtils = new BitmapUtils(mContext,裁剪 cropped, 400, msource); /** * 创建画位图的方法 * 获取到之前的点击动作数组 这样就可以获得到具体最终的图片的方向 * 并且依次按照图片方向进行旋转 */ Component.DrawTask drawTask = new Component.DrawTask() { @Override public void onDraw(Component component, Canvas canvas) { //获得行为动作 int[] action = CropImageView.getActionResult(); //获得动作数目 int actionIndex = CropImageView.getActionIndexResult(); //循环执行旋转、翻转动作 for (int i = 0; i < actionIndex; i++) { if (action[i] == 1) { //rotate图像 canvas.rotate(90,鸿蒙鸿蒙 bitmapUtils.getRealPixelMapWidth() / 2 * ratio, bitmapUtils.getRealPixelMapHeight() / 2 * ratio); } else if (action[i] == 2) { //水平翻转 //向下移动高度 canvas.translate(bitmapUtils.getRealPixelMapWidth() * ratio, 0); //向y轴负方向缩放一倍 canvas.scale(-1f, 1f); } else if (action[i] == 3) { //垂直翻转 //向下移动高度 canvas.translate(0, bitmapUtils.getRealPixelMapHeight() * ratio); //向y轴负方向缩放一倍 canvas.scale(1f, -1f); } } //按照原来的比例进行缩放 canvas.scale(ratio , ratio); //画图 canvas.drawPixelMapHolder(pixelMapHolder, 200, 230, new Paint()); } }; //为component增加drawtask方法 component.addDrawTask(drawTask); } } public static PixelMap getCroppedPixelMap(){ return CropOverlayView.getCroppedPixelMap(); } public static final class ActivityBuilder { //设置图片的Uri private final Uri mSource; //需要跳转回的bundle的名字 private String bundleName; //需要跳转回的Ability的名字 private String abilityName; //request_code private int request_code; //初始化 记录一些信息 private ActivityBuilder(Uri source , String bundle , String ability , int request) { mSource = source; bundleName = bundle; abilityName = ability; request_code = request; } //返回一个intent public Intent getIntent(Context context) { return getIntent(context, CropImageActivity.class); } //返回一个intent 用来实现页面跳转 public Intent getIntent(Context context, Class<?> cls) { Intent intent = new Intent(); intent.setParam("source", msource); if(bundleName != null){ intent.setParam("bundleName" , bundleName); } if(abilityName != null){ intent.setParam("abilityName" , abilityName); } if(request_code != 0){ intent.setParam("request_code" , request_code); } return intent; } //页面跳转 public void start(Ability ability, AbilitySlice abilitySlice) { start(ability, abilitySlice, request_code); } //页面跳转 public void start(Ability ability, AbilitySlice abilitySlice, int requestCode) { //给crop添加操作 AbilitySlice cropImageAbilitySlice = new CropImageActivity(); abilitySlice.presentForResult(cropImageAbilitySlice, getIntent(ability), requestCode); } //设置资源图片,被裁减的模式图片的id public ActivityBuilder setSource(int source) { msource = source; return this; } //设置context public ActivityBuilder setContext(Context context) { mContext = context; return this; } //设置需要跳转回的bundle名字 public ActivityBuilder setBundleName(String s){ bundleName = s; return this; } //设置需要跳转回的ability名字 public ActivityBuilder setAbilityName(String s){ abilityName = s; return this; } //设置需要跳转回时的code public ActivityBuilder setRequset_code(int i){ request_code = i; return this; } } } package com.example.javahm9.util; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.aafwk.content.Operation; import ohos.agp.colors.RgbColor; import ohos.agp.components.Button; import ohos.agp.components.Component; import ohos.agp.components.DependentLayout; import ohos.agp.components.element.ShapeElement; import ohos.agp.utils.RectFloat; import ohos.bundle.AbilityInfo; import ohos.media.image.PixelMap; import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; /** * @Author 李欣 * * 此类为裁剪功能实现的主要页面 * * 此页面上显示了一些功能性的button * 还有被裁减图片以及裁剪框 */ public class CropImageActivity extends AbilitySlice { //定义此slice的Dependent布局 private DependentLayout myLayout = new DependentLayout(this); //被裁减图片 private Component mPicture; //被裁减图片的位图 private PixelMap mPixelMap; //位图工具类 private BitmapUtils mBitmapUtils; //屏幕工具类 private CropWindowHandler mCropWindowHandler; //裁剪框 private Component mCropBound; //裁剪框工具类 private CropOverlayView mCropOverlayView; //图片资源 private int mSource; //图片上边距 private final int topIndex = 400; //图片工具类 private CropImageView mCropImageView; //裁减结果的矩阵 public static RectFloat croppedRectFloat; //裁减结果的亿华云pixelmap public static PixelMap croppedPixelMap; @Override public void onStart(Intent intent) { super.onStart(intent); //创建本slice的布局文件 DependentLayout.LayoutConfig config = new DependentLayout.LayoutConfig(MATCH_PARENT, MATCH_PARENT); //设置默认竖屏 setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT); //设置布局的背景 myLayout.setLayoutConfig(config); ShapeElement element = new ShapeElement(); element.setRgbColor(new RgbColor(255, 255, 255)); myLayout.setBackground(element); //设置button,image等 setupViews(intent); //加载裁剪框、背景图片等等 loadInput(); //加载布局 super.setUIContent(myLayout); } //按钮和图片初始化 private void setupViews(Intent intent) { buttonInit(intent); imageInit(intent); } //按钮初始化 private void buttonInit(Intent intent) { //创建button Button cancel = cancelButton(intent); Button rotate = rotateButton(); // Button horfilp = horizontalFilpButton(); // Button verfilp = verticalFilpButton(); Button crop = cropButton(intent); //将button添加到布局 myLayout.addComponent(cancel); myLayout.addComponent(rotate); // myLayout.addComponent(horfilp); // myLayout.addComponent(verfilp); myLayout.addComponent(crop); } //取消按钮 private Button cancelButton(Intent intent) { //创建取消button Button cancel = new Button(this); //为button增加布局条件 DependentLayout.LayoutConfig cancelLayoutConfig = new DependentLayout.LayoutConfig(); cancelLayoutConfig.setMargins(140,图片 50, 0, 0); cancelLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_TOP); cancelLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_PARENT_LEFT); //设置背景颜色 cancel.setLayoutConfig(cancelLayoutConfig); ShapeElement cancelElement = new ShapeElement(); cancelElement.setRgbColor(new RgbColor(155, 155, 155)); cancelElement.setCornerRadius(25); cancel.setBackground(cancelElement); //设置文本 cancel.setText("取消"); cancel.setTextSize(55); cancel.setHeight(180); cancel.setWidth(220); //绑定点击方法 cancel.setClickedListener(new Component.ClickedListener() { public void onClick(Component v) { //为按钮绑定方法 cancel(intent); } }); return cancel; } //旋转按钮 private Button rotateButton() { //创建旋转button Button rotate = new Button(this); //为button增加布局条件 DependentLayout.LayoutConfig rotateLayoutConfig = new DependentLayout.LayoutConfig(); rotateLayoutConfig.setMargins(500, 50, 0, 0); rotateLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_TOP); rotateLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_PARENT_LEFT); rotate.setLayoutConfig(rotateLayoutConfig); //设置背景颜色 ShapeElement rotateElement = new ShapeElement(); rotateElement.setRgbColor(new RgbColor(255, 228, 181)); rotateElement.setCornerRadius(25); rotate.setBackground(rotateElement); //设置文本 rotate.setText("旋转"); rotate.setTextSize(55); rotate.setHeight(180); rotate.setWidth(220); //绑定点击方法 rotate.setClickedListener(new Component.ClickedListener() { public void onClick(Component v) { rotate(); } }); return rotate; } //水平翻转按钮 private Button horizontalFilpButton() { //创建翻转button Button filp = new Button(this); //为button增加布局条件 DependentLayout.LayoutConfig filpLayoutConfig = new DependentLayout.LayoutConfig(); filpLayoutConfig.setMargins(0, 50, 300, 0); filpLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_TOP); filpLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_PARENT_RIGHT); //设置背景颜色 filp.setLayoutConfig(filpLayoutConfig); ShapeElement filpElement = new ShapeElement(); filpElement.setRgbColor(new RgbColor(180, 238, 180)); filpElement.setCornerRadius(25); filp.setBackground(filpElement); //设置文本 filp.setText("horFilp"); filp.setTextSize(40); filp.setHeight(85); filp.setWidth(220); //绑定点击方法 filp.setClickedListener(new Component.ClickedListener() { public void onClick(Component v) { horizontalFlip(); } }); return filp; } //垂直翻转按钮 private Button verticalFilpButton() { //创建翻转button Button filp = new Button(this); //为button增加布局条件 DependentLayout.LayoutConfig filpLayoutConfig = new DependentLayout.LayoutConfig(); filpLayoutConfig.setMargins(0, 145, 300, 0); filpLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_TOP); filpLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_PARENT_RIGHT); //设置背景颜色 filp.setLayoutConfig(filpLayoutConfig); ShapeElement filpElement = new ShapeElement(); filpElement.setRgbColor(new RgbColor(180, 238, 180)); filpElement.setCornerRadius(25); filp.setBackground(filpElement); //设置文本 filp.setText("verFilp"); filp.setTextSize(40); filp.setHeight(85); filp.setWidth(220); //绑定点击方法 filp.setClickedListener(new Component.ClickedListener() { public void onClick(Component v) { verticalFlip(); } }); return filp; } //裁剪按钮 private Button cropButton(Intent intent) { //创建裁剪button Button crop = new Button(this); //为button增加布局条件 DependentLayout.LayoutConfig cropLayoutConfig = new DependentLayout.LayoutConfig(); cropLayoutConfig.setMargins(820, 50, 0, 0); cropLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_TOP); cropLayoutConfig.addRule(DependentLayout.LayoutConfig.ALIGN_PARENT_LEFT); //设置背景颜色 crop.setLayoutConfig(cropLayoutConfig); ShapeElement cropElement = new ShapeElement(); cropElement.setRgbColor(new RgbColor(0, 125, 155)); cropElement.setCornerRadius(25); crop.setBackground(cropElement); //设置文本 crop.setText("裁剪"); crop.setTextSize(55); crop.setHeight(180); crop.setWidth(220); //绑定点击方法 crop.setClickedListener(new Component.ClickedListener() { public void onClick(Component v) { crop(intent); } }); return crop; } //图片初始化 private void imageInit(Intent intent) { //获得图片的id int source = intent.getIntParam("source", 0); mSource = source; //根据图片id获取pixelmap PixelMap pixelMapOriginal = BitmapUtils.getOriginalPixelMap(this, mSource).get(); mPixelMap = pixelMapOriginal; //创建bitmaputils工具类,获得位图相关数据 BitmapUtils bitmapUtils = new BitmapUtils(this ,裁剪 mPixelMap ,topIndex , mSource ); //创建cropwindowhandler工具类,获得windows相关数据 CropWindowHandler cropWindowHandler = new CropWindowHandler(this); //创建图片工具类,鸿蒙鸿蒙用来获得图片 mCropImageView = new CropImageView(mPixelMap ,模式 this , mSource , topIndex); //获取展示图片的component mPicture = mCropImageView.getmPicture(); //计算图片的位置,使得图片居中显示,图片计算出图片距离屏幕左边的空白 int margin = cropWindowHandler.getWindowWidth()/2 - bitmapUtils.getPixelMapWidth()/2; //给mPicture增加布局 DependentLayout.LayoutConfig componentLayoutConfig = new DependentLayout.LayoutConfig(); componentLayoutConfig.setMargins(0, topIndex, 0, 0);//边距 mPicture.setLayoutConfig(componentLayoutConfig); //将图片加入布局 myLayout.addComponent(mPicture); } //初始化工具类,加载裁剪框等等 private void loadInput() { //创建位图工具类 mBitmapUtils = new BitmapUtils(this, mPixelMap, 400, mSource); //创建屏幕工具类 mCropWindowHandler = new CropWindowHandler(this); //创建裁剪框的工具类 mCropOverlayView = new CropOverlayView(this, mBitmapUtils, mCropWindowHandler); //获得裁剪框 mCropBound = mCropOverlayView.getmCropBound(); //将裁剪框加入布局文件 myLayout.addComponent(mCropBound); } //取消裁剪方法 private void cancel(Intent intentOriginal) { Intent intent = new Intent(); //增加裁剪状态及结果 intent.setParam("cropFlag", !CropImage.CROPFLAG); intent.setParam("cropStatus", 1); // 通过Intent中的OperationBuilder类构造operation对象,指定设备标识(空串表示当前设备)、应用包名、Ability名称 Operation operation = new Intent.OperationBuilder() .withDeviceId("") .withBundleName(intentOriginal.getStringParam("bundleName")) .withAbilityName(intentOriginal.getStringParam("abilityName")) .build(); // 把operation设置到intent中 intent.setOperation(operation); //跳转 startAbility(intent); } //图片旋转的方法 private void rotate(){ //图片旋转 mCropImageView.rotateOnce(); //裁剪框旋转 mCropOverlayView.rotateOnce(); } //图片水平翻转的方法 private void horizontalFlip(){ //图片翻转 mCropImageView.horizontalFilp(); //裁剪框翻转 mCropOverlayView.horizontalFilpOnce(); } //图片垂直翻转的方法 private void verticalFlip(){ mCropImageView.verticalFilp(); //裁剪框翻转 mCropOverlayView.verticalFilpOnce(); } //成功裁剪方法 private void crop(Intent intentOriginal) { //计算裁减后的pixelmap并存放于cropoverlayview中 mCropOverlayView.croppedPixel(this); //显示到MainActivity Intent intent = new Intent(); //增加裁剪状态及结果 intent.setParam("cropFlag", CropImage.CROPFLAG); intent.setParam("cropStatus", 2); intent.setParam("result_code" , 203); RectFloat cropRect = mCropOverlayView.getmCropRect(); //塞入裁剪结果 intent.setParam("resultImg", mSource); croppedRectFloat = mCropOverlayView.getmCropRect(); croppedPixelMap = mPixelMap; // 通过Intent中的OperationBuilder类构造operation对象,指定设备标识(空串表示当前设备)、应用包名、Ability名称 Operation operation = new Intent.OperationBuilder() .withDeviceId("") .withBundleName(intentOriginal.getStringParam("bundleName")) .withAbilityName(intentOriginal.getStringParam("abilityName")) .build(); // 把operation设置到intent中 intent.setOperation(operation); //跳转 startAbility(intent); } @Override protected void onStop() { super.onStop(); } }想了解更多内容,请访问:
和华为官方合作共建的服务器托管鸿蒙技术社区
https://harmonyos.51cto.com