实现图片Bitmap简单编辑的三种方式

最近的安卓开发中遇到了一个看起来比较棘手的问题:三方分享图片,刚开始的需求仅仅是分享(动漫图片类app)画作主图,使用的是友盟的。友盟支持纯图片分享,要提供一个bitmap

<span style="white-space:pre">		</span>UMImage img = new UMImage(context, bmp);
		//设置微信好友分享内容
		WeiXinShareContent weixinContent = new WeiXinShareContent();
		//设置分享图片
		weixinContent.setShareImage(img);
		mController.setShareMedia(weixinContent);
		//设置微信朋友圈分享内容
		CircleShareContent circleMedia = new CircleShareContent();
		//设置朋友圈title
		circleMedia.setTitle(title);
		circleMedia.setShareImage(img);
		mController.setShareMedia(circleMedia);
刚开始没什么问题。


之后,产品把需求改了,需要在画作主图中添加水印表明画师头像,画师名,画作描述,以及相应的app二维码图片;


由于这个功能ios最先开始做,我就向ios取经。而ios那边的做法是使用view转bitmap,于是到网上查找相应的资料

   方案一:ios的方案

private Bitmap getShareBitmap() {
		View headerView = LayoutInflater.from(mActivity).inflate(
				R.layout.fragment_share, null);
		SimpleDraweeView img_user = (SimpleDraweeView)headerView.findViewById(R.id.img_user);
		TextView comic_name = (TextView)headerView.findViewById(R.id.comic_name);
		TextView comic_title = (TextView)headerView.findViewById(R.id.comic_title);
		FrescoHelper.displayImage2Cir(img_user, resp.data.avatar, true);
		comic_title.setText(resp.data.content);
		comic_name.setText(resp.data.nickname);
		int name_height = getFontHeight(DisplayUtils.sp2px(getActivity(),18.0f));
		int title_height = getFontHeight(DisplayUtils.sp2px(getActivity(),16.0f));
		int bottom_height = getFontHeight(DisplayUtils.sp2px(getActivity(),14.0f));
		int viewHight = name_height+title_height*2+bottom_height+96+50;
		return	BitmapUtils.getViewBitmap(headerView,(int)StringUtils.getScreenWidth(),viewHight);
	}
 /**
     * 把View绘制到Bitmap上
     * @param view 需要绘制的View
     * @param width 该View的宽度
     * @param height 该View的高度
     * @return 返回Bitmap对象
     */
    public static Bitmap getViewBitmap(View view, int width, int height) {
        Bitmap bitmap = null;
        if (view != null) {
            view.clearFocus();
            view.setPressed(false);
            boolean willNotCache = view.willNotCacheDrawing();
            view.setWillNotCacheDrawing(false);
            int color = view.getDrawingCacheBackgroundColor();
            view.setDrawingCacheBackgroundColor(0);
            float alpha = view.getAlpha();
            view.setAlpha(1.0f);
            if (color != 0) {
                view.destroyDrawingCache();
            }
            int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
            int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
            view.measure(widthSpec, heightSpec);
            view.layout(0, 0, width, height);
            view.buildDrawingCache();
            Bitmap cacheBitmap = view.getDrawingCache();
            if (cacheBitmap == null) {
                Log.e("view.ProcessImageToBlur", "failed getViewBitmap(" + view + ")",
                        new RuntimeException());
                return null;
            }
            bitmap = Bitmap.createBitmap(cacheBitmap);
            cacheBitmap.recycle();
            cacheBitmap = null;
            view.setAlpha(alpha);
            view.destroyDrawingCache();
            view.setWillNotCacheDrawing(willNotCache);
            view.setDrawingCacheBackgroundColor(color);
        }
        return bitmap;
    }
headerView是一个自己布局的linerLayout形式
这样看起来是没什么问题,一测试对于特别的长图(画作主图个别存在高度是宽度的10倍)会带导致OOM,方案一舍弃


方案二:自定义拼接bitmap

这个方案需要缩放,否则可能会OOM,缩放分画师主图缩放和底部描述缩放两种

主图缩放主要是为了对应长图,地图缩放主要是对应于高度不高的短图,直接上代码拼接代码那块就不贴出来了

private Bitmap createShareBitmap(Bitmap topBtp,Bitmap btnBtp) {
		if (null ==topBtp ||null==btnBtp) {
			Logger.d("src == null");
			return null;
		}
		//头部的测量宽高
		int topWid = topBtp.getWidth(),topHig = topBtp.getHeight();
		int totalWid,totalHig;
		//底部的测量宽高
		int btnWid = btnBtp.getWidth(),btnhig = btnBtp.getHeight();
		//整体的btn设置
		Bitmap allBtp;
		if(topBtp.getHeight()>2000){
			//头部的高度大于2K,即为长图,缩放底部的Bitmap,保持头部宽度不变,长图,高度计算
			totalWid = topWid;
			//缩放底部
			Matrix matrix = new Matrix();
			float scale = (float) topWid / btnWid;
			matrix.postScale(scale, scale);
			//缩放后的底部数据
			Bitmap btnScaleBtp = Bitmap.createBitmap(btnBtp, 0, 0, btnWid, btnhig, matrix, true);
			//总体的高度=缩放后底部高度+头部高度
			totalHig =topHig+btnScaleBtp.getHeight();
			// 创建位图
			allBtp = Bitmap.createBitmap(totalWid, totalHig, Bitmap.Config.RGB_565);
			Logger.d("totalWid="+totalWid+"totalHig="+totalHig);
			// 创建一个新的和SRC长度宽度一样的位图
			Canvas cv = new Canvas(allBtp);
			// 画底层图
			cv.drawBitmap(topBtp, 0, 0, null);// 在 0,0坐标开始画入src
			// 画水印
			cv.drawBitmap(btnScaleBtp, 0, topHig, null);// 在src的右下角画入水印
			// 保存位图
			cv.save(Canvas.ALL_SAVE_FLAG);// 保存
			cv.restore();// 存储
			recycleBitmap(btnScaleBtp);
			return allBtp;
		}else{
			//头部的高度小于2K,即为一般图,缩放头部的Bitmap,保持底部宽度不变即屏幕宽度
			totalWid = btnWid;
			//缩放头部
			Matrix matrix = new Matrix();
			float scale = (float) totalWid / topWid;
			matrix.postScale(scale, scale);
			//缩放后的底部数据
			Bitmap topScaleBtn = Bitmap.createBitmap(topBtp, 0, 0, topWid, topHig, matrix, true);
			//总体的高度=缩放后头部高度+底部高度
			totalHig =btnhig+topScaleBtn.getHeight();
			// 创建位图
			allBtp = Bitmap.createBitmap(totalWid, totalHig, Bitmap.Config.RGB_565);
			Logger.d("totalHig="+totalHig+"totalWid="+totalWid);
			// 创建一个新的和SRC长度宽度一样的位图
			Canvas cv = new Canvas(allBtp);
			// 画底层图
			cv.drawBitmap(topScaleBtn, 0, 0, null);// 在 0,0坐标开始画入src
			// 画水印
			cv.drawBitmap(btnBtp, 0, topScaleBtn.getHeight(), null);// 在src的右下角画入水印
			// 保存位图
			cv.save(Canvas.ALL_SAVE_FLAG);// 保存
			cv.restore();// 存储
			recycleBitmap(topScaleBtn);
			return allBtp;
		}
	}

暂时是解决问题了,但是感觉繁琐

方案三:Scrollview截图

一次无意间查看到关于android截屏的知识,看到关于截取超过屏幕的图片方法,其中一个ScrollView的截图方式

很简单,也分享给大家

/** 
     * 截取scrollview的屏幕 
     * @param scrollView 
     * @return 
     */  
    public static Bitmap getBitmapByView(ScrollView scrollView) {  
        int h = 0;  
        Bitmap bitmap = null;  
        // 获取scrollview实际高度  
        for (int i = 0; i < scrollView.getChildCount(); i++) {  
            h += scrollView.getChildAt(i).getHeight();  
            scrollView.getChildAt(i).setBackgroundColor(  
                    Color.parseColor("#ffffff"));  
        }  
        // 创建对应大小的bitmap  
        bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,  
                Bitmap.Config.RGB_565);  
        final Canvas canvas = new Canvas(bitmap);  
        scrollView.draw(canvas);  
        return bitmap;  
    }  

ScrollView截屏来源于:点击打开链接





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 图片编辑器源码是指用于在Android设备上对图片进行编辑和处理的代码。它包含了一系列功能,如裁剪、旋转、调整亮度/对比度/饱和度、添加滤镜、涂鸦等等。下面是一个简单Android图片编辑器源码的说明: 首先,图片编辑器源码应该包含一个图像处理的引擎,用于对图片进行各种编辑操作。这个引擎可以使用Android提供的图像处理库,如Bitmap类和Canvas类,或者使用第三方库,如OpenCV。 其次,图片编辑器源码应该实现各种编辑功能的方法。例如,裁剪功能可以通过指定裁剪区域的坐标和尺寸来实现,旋转功能可以通过旋转图片的矩阵变换来实现,调整亮度/对比度/饱和度可以通过修改每个像素的RGB值来实现,添加滤镜可以通过对每个像素应用滤镜效果来实现。 另外,图片编辑器源码还需要实现用户界面的设计和交互。这包括一个主界面,用于显示当前编辑图片编辑功能的选项,以及各种编辑功能的子界面,用于设置各种参数。用户界面可以使用Android提供的视图组件,如ImageView、Button和SeekBar等,来实现图片的显示和用户的操作。 最后,图片编辑器源码还应该包括保存编辑后的图片的功能。可以使用Android提供的文件存储API,将编辑后的图片保存到设备的存储器中,或者分享到其他应用程序。此外,还可以支持撤销和重做功能,以便用户可以在编辑过程中进行修改和还原。 总之,Android图片编辑器源码是一套用于在Android设备上对图片进行各种编辑和处理的代码。它包含了图像处理引擎、各种编辑功能的实现、用户界面的设计和交互,以及保存和分享图片的功能。通过这些源码,开发者可以自定义和扩展功能,实现自己想要的图片编辑器应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值