任意不规则形状的图片剪裁 .

原理:根据选择的区域(区域的选择需要用到GraphicsPath),根据区域可以得到这部分区域的边境矩形,从而不需要循环整张图片,只需要循环边境矩形,将矩形中的选择区域复制到另一种图片,这样大大提高了效率。根据选择的区域,可以得到复制出位于GraphicsPath中的这部分图片,同时设置这部分图片为透明,同时还要设置另一种图片不在GraphicsPath内的区域为透明,这样看起来的效果就是从图片中扣出来的一样,意思和PhotoShop的套索工具差不多。

说得有点晕了,还是看效果图吧:(左边是剪裁出来的图)

下面说说关键的代码。

方法一:像素级的处理,循环整张图片,一个一个像素复制出来,效率比较低。

方法二:指针法,效率得到提升。

  /// <summary>        /// 剪裁选定区域的图片        /// </summary>        /// <param name="bitmap">原图</param>        /// <param name="path">用户选定的区域</param>        /// <param name="outputBitmap">剪裁出来的图(输出图)</param>        /// <returns></returns>        public static Bitmap BitmapCrop(Bitmap bitmap, GraphicsPath path, out Bitmap outputBitmap)        {            Rectangle rect = Rectangle.Round(path.GetBounds());            outputBitmap = new Bitmap(rect.Width, rect.Height);            if (bitmap == null) return null;

            Bitmap bmp = (Bitmap)bitmap.Clone();            bitmap.Dispose();            BitmapData data = bmp.LockBits(rect,                ImageLockMode.ReadWrite, bmp.PixelFormat);            BitmapData outData = outputBitmap.LockBits(new Rectangle(0, 0, rect.Width, rect.Height),                ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);            unsafe            {                byte* q = (byte*)outData.Scan0;                int offset = outData.Stride - rect.Width * 4;                int PixelSize = 4;                for (int y = rect.Top; y < rect.Top + rect.Height; y++)                {                    //每一行内存中的位置                    byte* row = (byte*)data.Scan0 + ((y - rect.Top) * data.Stride);                    for (int x = rect.Left; x < rect.Left + rect.Width; x++)                    {                        //判断坐标点是否在路径中                        //在路径中,则复制原图这部分给输出图,同时设置原图这部分透明                        //坐标点和内存中值的对应                        if (path.IsVisible(x, y))                          {                            q[0] = row[(x - rect.Left) * PixelSize];                            q[1] = row[(x - rect.Left) * PixelSize + 1];                            q[2] = row[(x - rect.Left) * PixelSize + 2];                            q[3] = row[(x - rect.Left) * PixelSize + 3];

                            row[(x - rect.Left) * PixelSize + 3] = 0;                        }                        else //不在路径中,则设置输出图这部分为透明                        {                            q[3] = 0;                        }                        q += 4;                    }                    q += offset;                }            }            bmp.UnlockBits(data);            outputBitmap.UnlockBits(outData);

            return bmp;        }
 

注意:因为有不安全代码,所以要设置项目的属性 ->生成,勾选允许不安全代码。

时间: 2024-10-15 18:06:39

任意不规则形状的图片剪裁 .的相关文章

让您的电脑在任意目录可以支持图片的粘贴,试试看呗(第二篇)~

继上一篇随笔 让您的电脑在任意目录可以支持图片的粘贴,试试看呗. http://www.cnblogs.com/guizhouhehai/p/4702294.html 首先要感谢,大家给出的建议与意见.也谢谢大家的鼓励~ 有指出代码中的BUG的朋友,有指点我的大牛.在这里谢谢大家. 嗯哈,那接下来开始这篇随笔的主题了咯. 上一次无意中的一个小玩意儿,个人感觉还是方便了不少.但是不够完美. 比如Windows10下面右键菜单没有,无法使用系统ctrl+v等快捷等等缺点. 经过周六一天对程序的调整,

Android开发实践:自己动手编写图片剪裁应用(1)

最近利用一周左右的业余时间,终于完成了一个Android图片剪裁库,核心功能是根据自己的理解实现的,部分代码参考了Android源码的图片剪裁应用.现在将该代码开源在Github上以供大家学习和使用,地址:https://github.com/Jhuster/ImageCropper,效果如下所示: 我的大致计划是首先介绍一下这个库的用法,然后再写几篇文章介绍一下其中的一些原理和关键技术,希望对Android开发新手有所帮助. [特性] 支持通过手势移动和缩放剪裁窗口 支持固定剪裁窗口大小.固定

Android开发实践:自己动手编写图片剪裁应用(2)

上篇文章主要介绍了我开源在Github上的图片剪裁库(ImageCropper)的基本特性和用法,从本文开始,慢慢介绍一些开发图片剪裁应用中涉及的知识点和技术. 其实Android系统本身也提供了图片剪裁的模块,我们可以直接通过Intent来调用系统的图片剪裁功能,本文我们就先了解一下系统自带的图片剪裁功能是如何调用的吧. 得到被剪裁图片的URL地址 既然是图片剪裁,就一定要有被剪裁的图片,由于图片数据一般很大,为了防止内存溢出,普通APP与Android系统图片剪裁应用之间是通过URL来传递图

Android开发实践:自己动手编写图片剪裁应用(3)

前面两篇文章分别介绍了我编写的开源项目ImageCropper库,以及如何调用系统的图片剪裁模块,本文则继续分析一下开发Android图片剪裁应用中需要用到的Bitmap操作. 在Android系统中,对图片的操作主要是通过Bitmap类和Matrix类来完成,本文就介绍一下图片剪裁应用中对Bitmap的一些操作,包括:打开.保存.剪裁.旋转等,我已经将这些操作都封装到了一个BitmapHelper.java类中,放到GitHub上了(点击这里),大家可以方便地集成到自己的项目中. 打开图片 图

图片剪裁实现

图片剪裁实现:if (fileName.indexOf("HEIGHT") != -1) {                                                ByteArrayOutputStream bOutPutStream=new ByteArrayOutputStream();                        ImageTools.scaleByHeight(f.getInputStream(), fileName,         

图片剪裁控件——ClipImageView

这段时间在做自己的项目时,须要使用到图片剪裁功能,当时大概的思考了一些需求.想到了比較简单的实现方法.因此就抽了点时间做了这个图片剪裁控件--ClipImageView 这里先贴上ClipImageView的代码: package com.example.clipimage; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import a

插件介绍 :cropper是一款使用简单且功能强大的图片剪裁jQuery插件。

简要教程 cropper是一款使用简单且功能强大的图片剪裁jQuery插件.该图片剪裁插件支持图片放大缩小,支持鼠标滚轮操作,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用. cropper提供了大量的参数.方法和事件供图片的剪裁操作. 安装 可以通过Bower或NPM来安装该插件. 1 2 bower install cropper npm install cropper                使用方法 使用该图片剪裁插件首先要引入必要的js和css文件. 1 2

Android 拍照图片选取与图片剪裁

最近从以前的项目中扒下来一个常用的模块,在这里有必要记录一下的,就是android上获取图片以及裁剪图片,怎么样?这个功能是不是很常用啊,你随便打开一个App,只要它有注册功能都会有设置人物头像的功能,尤其在内容型的app中更为常见,那么这些功能是怎么实现的呢?今天,在这里就记录一下好了,防止以后的项目中也会用到,就直接拿来用好了. 1.通过拍照或者图册获取图片(不需要剪裁) 这种获取图片的方式就比较次了,因为不设置图片的剪裁功能,有可能因为图片过大,导致OOM,但是这种方式也是有必要讲一下的,

Android图片剪裁库

最近利用一周左右的业余时间,终于完成了一个Android图片剪裁库,核心功能是根据自己的理解实现的,部分代码参考了Android源码的图片剪裁应用.现在将该代码开源在Github上以供大家学习和使用,地址:https://github.com/Jhuster/ImageCropper,效果如下所示: 我的大致计划是首先介绍一下这个库的用法,然后再写几篇文章介绍一下其中的一些原理和关键技术,希望对Android开发新手有所帮助. [特性] 支持通过手势移动和缩放剪裁窗口 支持固定剪裁窗口大小.固定