精华内容
下载资源
问答
  • Delphi 图像局部放大

    热门讨论 2013-08-10 09:30:59
    Delphi实战源码,定义图片的放大区域,放大比例[1至100]1是最大\100是缩小,定义放大区域及放大过程,拖动滑块改变放大位数,实现图像放大功能。可把这个模块应用到你的Delphi项目中,做为图像放大功能也是很实用的...
  • opencv图片局部放大

    千次阅读 2019-08-12 20:57:26
    这里的on_Mouse函数一般需要event参数,表示处理事件,在我们的图片局部放大中,我们主要使用的形参是鼠标的坐标(x,y),其他几个变量没有涉及。 总结一下,我们的步骤主要分为以下几步。 第一步,复制到新的...

    本文可以正常运行,请放心使用。
    本文参考博客https://blog.csdn.net/pw1623/article/details/88429661,本文系为这篇博客的学习与改进,添加一些详细的注释,弥补原博客的不足之处。
    运行结果
    在这里插入图片描述在这里插入图片描述
    程序源代码(附详细注释)

    // fangdaPic.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    #include "pch.h"
    #include <iostream>
    #include<opencv2\opencv.hpp>
    using namespace std;
    using namespace cv;
    Mat org;//原图
    Mat img;//输出图片
    Mat imgROI;//感兴趣区域
    Mat roiResize;//感兴趣区域ROI的两倍
    Mat tranPart;
    int foo = 30;//定义尺寸
    int fooResize = 2 * foo;//最终显示放大镜的正方形区域的边长,用作下面if的判断
    
    //鼠标回调函数
    void on_Mouse(int event, int x, int y, int flag, void*ustc) {
    	//形参x,y是鼠标点击的位置
    	Mat img_temp = img.clone();//临时变量,存放原图
    	//if的作用,x,y是鼠标坐标,限定不能太靠近左上角x > fooResize和 y>fooResize,目的是能让放大镜显示出来。
    	//同时限定不能太靠近右下角x<img_temp.cols - fooResize和 y < img_temp.rows - fooResize
    	if (x > fooResize && x<img_temp.cols - fooResize && y>fooResize && y < img_temp.rows - fooResize) {
    		//感兴趣区域范围
    		imgROI = img_temp(Rect(x - foo, y - foo, 2 * foo, 2 * foo));//以(x,y)为中心,左右为foo做正方形
    		//tranPart是最后显示放大的区域,这里
    		tranPart = img_temp(Range(y - 2 * foo, y + 2 * foo), Range(x - 2 * foo, x + 2 * foo));//Range表示纵、横坐标的范围
    		//感兴趣区域放大两倍,需要和tranPart的尺寸搭配。可调,但是注意不能超过图片本身范围。
    		resize(imgROI, roiResize, Size(2 * imgROI.cols, 2 * imgROI.rows));//输出到roiResize这个Mat对象中
    		roiResize.copyTo(tranPart);//复制到tranPart这个Mat对象中
    	//标注鼠标的位置
    		circle(img_temp, Point(x, y), 10, Scalar(0, 0, 255), 1, 8, 0);//画一个简单的圆
    		imshow("img", img_temp);//显示窗口
    	}
    }
    
    int main() {
    	org = imread("1.jpg");//读取图片,此图片位于同一路径下
    	img = org.clone();
    	namedWindow("img");//创建opencv窗口
    	imshow("img", img);//在窗口显示图片
    	setMouseCallback("img", on_Mouse, 0);//调用鼠标回调函数
    	waitKey(0);
    }
    

    对代码的进一步解释
    大家可能对setMouseCallback()这个函数有点陌生。下面解释一下。如下转到定义我们可以看到。
    setMouseCallback有三个形参,第一个是const String&类型的变量,需要填写窗口的名称,我们这里是“img”。
    第二个形参是MouseCallBack类型的回调函数,第三个形参是void*类型的userdata=0采用默认值。

    CV_EXPORTS void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);
    
    /** @brief Gets the mouse-wheel motion delta, when handling mouse-wheel events cv::EVENT_MOUSEWHEEL and
    cv::EVENT_MOUSEHWHEEL.在处理鼠标滚轮事件时,获取鼠标滑轮的移动变化。
    
    For cv::EVENT_MOUSEWHEEL positive and negative values mean forward and backward scrolling,
    respectively.      EVENT_MOUSEWHEEL正负值意味着向前滚或者向后滚。
     For cv::EVENT_MOUSEHWHEEL, where available, positive and negative values mean right and
    left scrolling, respectively.
    With the C API, the macro CV_GET_WHEEL_DELTA(flags) can be used alternatively.
    有c接口的地方,这个标志可以替代使用。
    @note
    
    Mouse-wheel events are currently supported only on Windows.
    鼠标滚轮事件目前只支持windows系统
    @param flags The mouse callback flags parameter.鼠标回调标志参数
     */
    

    void on_Mouse(int event, int x, int y, int flag, void*ustc) ;
    这里的on_Mouse函数一般需要event参数,表示处理事件,在我们的图片局部放大中,我们主要使用的形参是鼠标的坐标(x,y),其他几个变量没有涉及。

    总结一下,我们的步骤主要分为以下几步。

    第一步,复制到新的临时变量中Mat img_temp = img.clone();//临时变量,存放原图
    第二步,考虑最终局部放大的尺寸,限定鼠标位置(x,y)。if (x > fooResize && x<img_temp.cols - fooResize && y>fooResize && y < img_temp.rows - fooResize)
    第三步,绘制最初的感兴趣区域ROI,这里是待放大的地方。imgROI = img_temp(Rect(x - foo, y - foo, 2 * foo, 2 * foo));//以(x,y)为中心,左右为foo做正方形
    第四步,设置放大后显示的地方与尺寸。tranPart = img_temp(Range(y - 2 * foo, y + 2 * foo), Range(x - 2 * foo, x + 2 * foo));//Range表示纵、横坐标的范围,此处是ROI区域的两倍,需要自己画图体会
    第五步,感兴趣区域ROI放大,放到tranPart中。resize(imgROI, roiResize, Size(2 * imgROI.cols, 2 * imgROI.rows));//输出到roiResize这个Mat对象中
    roiResize.copyTo(tranPart);//复制到tranPart这个Mat对象中
    第六步,显示inshow即可。

    展开全文
  • js 实现 图片的局部放大效果

    千次阅读 2013-07-19 17:59:55
    很多的网上商城都有鼠标在图片上移动时能将局部图放大的JS效果,今天自己也做了个,   实现该效果的原理是:在图片原有的宽高大小基础上再重新定义一个放大了X倍的图片,然后通过对大位置偏移的设置来起到放大...

    很多的网上商城都有鼠标在图片上移动时能将局部图放大的JS效果,今天自己也做了个,

     

    实现该效果的原理是:在图片原有的宽高大小基础上再重新定义一个放大了X倍的图片<img width=this.width*X,height=this.height*x scr='原图地址'/>,然后通过对大图位置偏移的设置来起到放大图片的效果。

    直接上代码:

    <head>
        <title></title>
        <script src="Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
        <style type="text/css" >
        #bigimg
        {
              position:absolute;
              display:none;
              overflow:hidden;
              height:200px;
              width:200px;
        }
        #smalldiv
        {
           position:absolute;
           display:none; 
              
        }
        </style>
        <script type="text/javascript">
            $(function () {
                var count = 0;
    
                $("#img").mousemove(function (e) {
                    var smalldiv = $("#smalldiv");
                    var ZoomSizeWidth = $("#img1").width() / $("#img_zoom").width(); //宽放大的倍数
                    var ZoomSizeHeight = $("#img1").height() / $("#img_zoom").height();//高放大的倍数
                    $("#bigimg").show();
                    smalldiv.show();
                    var mouseX = e.pageX + 5;
                    var mouseY = e.pageY + 5;
                 
    
                    if (e.pageX < $(this).offset().left + smalldiv.width() / 2) {//当鼠标的X坐标小于图片与div遮罩层的x坐标和是divx=0;
                        divX = 0;
                    }
                    else if (e.pageX > $(this).offset().left + smalldiv.width() / 2 && e.pageX < $(this).offset().left + $(this).width() - smalldiv.width() / 2) {//鼠标的X坐标在图片内部并且小于图片最右边的X坐标
                        divX = e.pageX - $(this).offset().left - smalldiv.width() / 2;
                    }
                    else if (e.pageX > $(this).offset().left + $(this).width() - smalldiv.width() / 2) {//鼠标的X坐标大于图片的最右边的X坐标 (Y轴同理)
                        divX = $(this).width() - smalldiv.width();
                    }
    
                    if (e.pageY < $(this).offset().top + smalldiv.height() / 2) {
                        divY = 0;
                    }
                    else if (e.pageY > $(this).offset().top + smalldiv.height() / 2 && e.pageY < $(this).offset().top + $(this).height() - smalldiv.height() / 2) {
                        divY = e.pageY - $(this).offset().top - smalldiv.height() / 2;
                    }
                    else if (e.pageY > $(this).offset().top - smalldiv.height()) {
                        divY = $(this).height() - smalldiv.height();
                    }
    
                    $("#bigimg").css("top", mouseY).css("left", mouseX);
                    smalldiv.css("top", divY).css("left", divX);
                    smalldiv.appendTo("#img");
                    var tempX = smalldiv.offset().left - $(this).offset().left;//通过对大图的位置偏移来起到放大的效果
                    var tempY = smalldiv.offset().top - $(this).offset().top;
                    $("#img1").css("top", -tempY * ZoomSizeHeight).css("left", -tempX * ZoomSizeWidth);
                });
    
                $("#img_zoom").mouseleave(function () {
                   
                    $("#smalldiv").hide();
                    $("#bigimg").hide();
                });
            })
        </script>
    </head>
    <body>
    <div id="img" style=" width:200px; height:200px;margin-left:200px; position:relative; margin-top:30px"><img alt="图片" src="images/Desert.jpg" id="img_zoom" width="200" height="200"/></div>
    <div id="bigimg" ><img  alt="放大后图片" id="img1" src="images/Desert.jpg" width="800px" height="800px" style="position:absolute" /></div>
    <div id="smalldiv" style="width:50px; background-color: rgba(0,0,0,0.5); height:50px; border:1px solid gray; "></div>
    </body>


     

    展开全文
  • 基于C++程序放大局部图形(mfc)

    千次阅读 2017-06-20 15:28:56
    基于C++程序放大局部图形;功能的实现;通过VC++实现对图形的局部进行放大;实现方法:;CDC类StretchBlt函数可以将一幅位图从;BOOLStretchBlt(;intx,inty,//目标矩形的坐标原点int;intxSrc,intySrc,//源矩形的...

    基于C++程序放大局部图形;功能的实现;通过VC++实现对图形的局部进行放大;实现方法:;CDC类StretchBlt函数可以将一幅位图从;BOOLStretchBlt(;intx,inty,//目标矩形的坐标原点int;intxSrc,intySrc,//源矩形的坐标;intnSrcWidth,intnSrcHeig;};;当指定的源和目标矩形的宽度或高度


    基于C++程序放大局部图形

    功能的实现

    通过VC++实现对图形的局部进行放大。编译并运行程序,如下图所示。在图形上移动鼠标光标放大显示图形的不同部位,单击鼠标左键减小放大赔率,单击鼠标右键增大放大倍率。

    实现方法:

    CDC类StretchBlt函数可以将一幅位图从一个源矩形以一定的光栅操作拷贝到另外一个不同大小的目标矩形,该函数的定义如下:

    BOOL StretchBlt(

    int x, int y, //目标矩形的坐标原点 int nWidth,int nHeight, //目标矩形的长度和宽度 CDC*pSrcDC, //源设备环境句柄

    int xSrc,int ySrc, //源矩形的坐标原点

    int nSrcWidth,int nSrcHeight, //源矩形的长度和宽度 DWORD dwRop //光栅操作标志

    };

    当指定的源和目标矩形的宽度或高度不同时,StretchBlt函数将创建一个位图的镜象。如果是宽度变化,就沿x轴创建镜像;如果是高度变化就沿y轴创建镜像。而且该函数可以再内存中对源图像做拉伸或压缩处理后在拷贝到目标距。这样就实现某部分位图的放大功能。

    编写步骤如下

    (1)通过AppWizard创建一个单文档应用程序ZoomPart。

    (2)在CZoomPartView类的头文件中增加以下保护类型的成员变量:

    protected:

    CSize m_sizeDest;

    CSize m_sizeSource;

    CBitmap * m_pBitmap;

    CDC * m_pdcMem;

    int oldx,oldy,s,d; //s确定被放大区域,d确定放大显示区域,放大倍率=d/s

    bool recover;

    long mana;

    (3)在资源中加入自己喜欢的位图,其ID设为IDB_BITMAP1。

    (4)在CZoomPartViewd的构造函数中初始化成员变量,其代码如下:

    CZoomPartView::CZoomPartView()

    {

    // TODO: add construction code here

    m_pdcMem = new CDC;

    m_pBitmap = new CBitmap;

    recover = true;

    s = 30; d = 45;

    mana = SRCCOPY;

    }

    (5)在CZoomPartViewd的析构函数中加入如下代码:

    CZoomPartView::~CZoomPartView()

    {

    delete m_pdcMem;

    delete m_pBitmap;

    }

    (6)在CZoomPartViewd的OnDraw函数中显示位图,其代码如下:

    void CZoomPartView::OnDraw(CDC* pDC)

    {

    CZoomPartDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    // TODO: add draw code for native data here

    //声明判断是否load位图的静态标志

    static bool load;

    //按原来大小显示位图

    if (!load) {

    BITMAP bm;

    load = !load;

    m_pBitmap->LoadBitmap(IDB_BITMAP1);

    m_pdcMem->CreateCompatibleDC(pDC);

    m_pdcMem->SelectObject(m_pBitmap);

    m_pBitmap->GetObject(sizeof(bm),&bm);

    m_sizeSource.cx = bm.bmWidth;

    m_sizeSource.cy = bm.bmHeight;

    m_sizeDest = m_sizeSource;

    pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,

    m_pdcMem,0,0,m_sizeSource.cx,m_sizeSource.cy,mana);

    }

    else {

    pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,

    m_pdcMem,0,0,m_sizeSource.cx,m_sizeSource.cy,mana);

    }

    (7)在CZoomPartViewd类中通过ClassWizard响应WM_MOUSEMOVE消息,根据当前放大倍数放大鼠标位置附近的局部图像,其代码如下:

    void CZoomPartView::OnMouseMove(UINT nFlags, CPoint point)

    {

    //计算要放大的局部矩形的源图像位置和目标位置

    CString cord;

    int dd;

    CRect srect,drect,mrect;

    srect.left = point.x - s;

    srect.top = point.y - s;

    srect.right = point.x + s;

    srect.bottom = point.y + s;

    drect.left = point.x - d;

    drect.top = point.y - d;

    } drect.right = point.x + d; drect.bottom = point.y + d; mrect.left = oldx - d; mrect.top = oldy - d; mrect.right = oldx + d; mrect.bottom = oldy + d; dd = 2*d; CDC * pDC = GetDC(); OnPrepareDC(pDC); //放大图像 if (recover) { pDC->BitBlt(mrect.left,mrect.top,dd,dd, m_pdcMem,mrect.left,mrect.top,mana); } pDC->StretchBlt(drect.left,drect.top, drect.Width(),drect.Height(),m_pdcMem,srect.left, srect.top,srect.Width(),srect.Height(),SRCCOPY); oldx = point.x; oldy = point.y; ReleaseDC(pDC); recover = true; CView::OnMouseMove(nFlags, point);

    (8)在CZoomPartViewd类中通过ClassWizard响应WM_LBUTTONDOWN消息和WM_RBUTTONDOWN消息,减小和增加放大倍数,然后进行放大显示。其代码如下:

    void CZoomPartView::OnLButtonDown(UINT nFlags, CPoint point)

    {

    //如果鼠标位置不在位图上,则还原位图大小显示

    CRect rc(0,0,m_sizeSource.cx,m_sizeSource.cy);

    if(!rc.PtInRect(point))

    {

    Invalidate();

    }

    else if (d > 5)//如果放大倍数大于5,就继续减小放大倍数,然后进行放大显示 {

    CDC * pDC = GetDC();

    pDC->StretchBlt(oldx - d,oldy - d,2*d,

    2*d,m_pdcMem,oldx - d,oldy - d,2*d,2*d,mana);

    d -= 10;

    ReleaseDC(pDC);

    CZoomPartView::OnMouseMove(nFlags, point);

    }

    CView::OnLButtonDown(nFlags, point);

    }

    void CZoomPartView::OnRButtonDown(UINT nFlags, CPoint point)

    {

    //如果鼠标位置不在位图上,则还原位图大小显示

    CRect rc(0,0,m_sizeSource.cx,m_sizeSource.cy);

    if(!rc.PtInRect(point))

    {

    Invalidate();

    }

    else if (d <150)//如果放大倍数小于150,就继续增加放大倍数,然后进行放大显示 {

    d += 10;

    CZoomPartView::OnMouseMove(nFlags, point);

    }

    CView::OnRButtonDown(nFlags, point);

    }


    展开全文
  • 零、前言: 本文的知识点一览 ...3.本文会实现两个自定义控件:FitImageView(图片自适应)和BiggerView(放大镜),前者为后者作为铺垫。 4.最后会介绍如何从guihub生成自己的依赖库,这样一个完整的自定义...
        

    零、前言:

    本文的知识点一览

    1.自定义控件及自定义属性的写法,你也将对onMesure有更深的认识
    2.关于bitmap的简单处理,及canvas区域裁剪
    3.本文会实现两个自定义控件:FitImageView(图片自适应)BiggerView(放大镜),前者为后者作为铺垫。
    4.最后会介绍如何从guihub生成自己的依赖库,这样一个完整的自定义控件库便ok了。
    5.本项目源码见文尾捷文规范第一条

    实现效果一览:

    1.放大镜效果1:

    9414344-748958617232b4f3.gif
    放大镜效果1.gif

    2.放大镜效果2:(使用了clipOutPath需要API26)

    9414344-ff733f2bd5499cbb.gif
    放大镜效果2.gif
    3.该控件已做成类库(欢迎star),使用:
        allprojects {
            repositories {
                ...
                maven { url 'https://jitpack.io' }
            }
        }
        
        dependencies {
                implementation 'com.github.toly1994328:BiggerView:v1.01'
        }
    

    一、宽高等比例自适应的控件:FitImageView

    一开始想做放大镜效果,没多想就继承ImageView了,后来越做越困难,bitmap的裁剪模式会影响视图中显示图片的大小。
    而View自己的的大小不变,会导致图片显示宽高捕捉困难,和图片左上角捕捉困难。
    这就会导致绘制放大图片时的定位适配困难,那么多裁剪模式,想想都崩溃。
    于是我想到,自己定义图像显示的view算了,需求是宽高按比例适应,并且View的尺寸即图片的尺寸,
    将蓝色作为背景,结果如下,你应该明白是什么意思了吧,就是既想要图片不变形,又想不要超出的背景区域:

    9414344-5308d12f6f1bf129.png
    宽大于高.png
    9414344-ad744b38415eb67e.png
    高大于宽.png

    1.自定义属性:
        <!--图片放大镜-->
        <declare-styleable name="FitImageView">
            <!--图片资源-->
            <attr name="z_fit_src" format="reference"/>
        </declare-styleable>
    
    2.自定义控件初始代码
    /**
     * 作者:张风捷特烈<br/>
     * 时间:2018/11/19 0019:0:14<br/>
     * 邮箱:1981462002@qq.com<br/>
     * 说明:宽高自适应图片视图
     */
    public class FitImageView extends View {
    
        private Paint mPaint;//主画笔
        private Drawable mFitSrc;//自定义属性获取的Drawable
        private Bitmap mBitmapSrc;//源图片
        protected Bitmap mFitBitmap;//适应宽高的缩放图片
    
        protected float scaleRateW2fit = 1;//宽度缩放适应比率
        protected float scaleRateH2fit = 1;//高度缩放适应比率
        protected int mImageW, mImageH;//图片显示的宽高
    
        public FitImageView(Context context) {
            this(context, null);
        }
    
        public FitImageView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs,0);
        }
    
        public FitImageView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FitImageView);
            mFitSrc = a.getDrawable(R.styleable.FitImageView_z_fit_src);
            a.recycle();
            init();//初始化
        }
    
        private void init() {
            //初始化主画笔
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mBitmapSrc = ((BitmapDrawable) mFitSrc).getBitmap();//获取图片
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //TODO draw
        }
    
    3.测量及摆放:(这是核心处理)
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mImageW = dealWidth(widthMeasureSpec);//显示图片宽
        mImageH = dealHeight(heightMeasureSpec);//显示图片高
        float bitmapWHRate = mBitmapSrc.getHeight() * 1.f / mBitmapSrc.getWidth();//图片宽高比
        if (mImageH >= mImageW) {
            mImageH = (int) (mImageW * bitmapWHRate);//宽小,以宽为基准
        } else {
           mImageW = (int) (mImageH / bitmapWHRate);//高小,以高为基准
        }
        setMeasuredDimension(mImageW, mImageH);
    }
    
    
    /**
     * @param heightMeasureSpec
     * @return
     */
    private int dealHeight(int heightMeasureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            //控件尺寸已经确定:如:
            // android:layout_height="40dp"或"match_parent"
            scaleRateH2fit = size * 1.f / mBitmapSrc.getHeight() * 1.f;
            result = size;
        } else {
            result = mBitmapSrc.getHeight();
            if (mode == MeasureSpec.AT_MOST) {//最多不超过
                result = Math.min(result, size);
    
            }
        }
        return result;
    }
    
    
    /**
     * @param widthMeasureSpec
     */
    private int dealWidth(int widthMeasureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            //控件尺寸已经确定:如:
            // android:layout_XXX="40dp"或"match_parent"
            scaleRateW2fit = size * 1.f / mBitmapSrc.getWidth();
            result = size;
    
        } else {
            result = mBitmapSrc.getWidth();
            if (mode == MeasureSpec.AT_MOST) {//最多不超过
                result = Math.min(result, size);
            }
        }
        return result;
    }
    
    4.创建缩放后的bitmap及绘制

    创建的时机选择在onLayout里,因为要先测量后才能知道缩放比

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mFitBitmap = createBigBitmap(Math.min(scaleRateW2fit, scaleRateH2fit), mBitmapSrc);
        mBitmapSrc = null;//原图已无用将原图置空
    }
    
    /**
     * 创建一个rate倍的图片
     *
     * @param rate 缩放比率
     * @param src  图片源
     * @return 缩放后的图片
     */
    protected Bitmap createBigBitmap(float rate, Bitmap src) {
        Matrix matrix = new Matrix();
        //设置变换矩阵:扩大3倍
        matrix.setValues(new float[]{
                rate, 0, 0,
                0, rate, 0,
                0, 0, 1
        });
        return Bitmap.createBitmap(src, 0, 0,
                src.getWidth(), src.getHeight(), matrix, true);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mFitBitmap, 0, 0, mPaint);
    }
    

    一、自定义控件:BiggerView

    1.自定义属性:attrs.xml
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!--图片放大镜-->
        <declare-styleable name="BiggerView">
            <!--半径-->
            <attr name="z_bv_radius" format="dimension"/>
            <!--边线宽-->
            <attr name="z_bv_outline_width" format="dimension"/>
            <!--进度色-->
            <attr name="z_bv_outline_color" format="color"/>
            <!--放大倍率-->
            <attr name="z_bv_rate" format="float"/>
        </declare-styleable>
    </resources>
    
    2.初始化自定义控件
    public class BiggerView extends FitImageView {
        private int mBvRadius = dp(30);//半径
        private int mBvOutlineWidth = 2;//边线宽
    
        private float rate = 4;//默认放大的倍数
        private int mBvOutlineColor = 0xffCCDCE4;//边线颜色
    
        private Paint mPaint;//主画笔
        private Bitmap mBiggerBitmap;//放大的图片
        private Path mPath;//剪切路径
    
        public BiggerView(Context context) {
            this(context, null);
        }
    
        public BiggerView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public BiggerView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BiggerView);
            mBvRadius = (int) a.getDimension(R.styleable.BiggerView_z_bv_radius, mBvRadius);
            mBvOutlineWidth = (int) a.getDimension(R.styleable.BiggerView_z_bv_outline_width, mBvOutlineWidth);
            mBvOutlineColor = a.getColor(R.styleable.BiggerView_z_bv_outline_color, mBvOutlineColor);
            rate = (int) a.getFloat(R.styleable.BiggerView_z_bv_rate, rate);
            a.recycle();
            init();
        }
    
        private void init() {
            //初始化主画笔
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(mBvOutlineColor);
            mPaint.setStrokeWidth(mBvOutlineWidth * 2);
            mPath = new Path();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            }
        }
    }
    

    二、初级阶段

    点击的时候生成一个圆球,并随着手指移动跟随移动,松开手时消失,如图:
    这个小球就是将来展示局部放大效果的地方

    9414344-a7ab3d9439b9ea86.gif
    初阶效果.gif
    1.添加成员变量:
    private int mBvRadius = dp(30);//半径
    private Paint mPaint;//主画笔
    
    private float mCurX;//当前触点X
    private float mCurY;//当前触点Y
    private boolean isDown;//是否触摸
    
    2.触点的处理
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                isDown = true;
                mCurX = event.getX();
                mCurY = event.getY();
                break;
            case MotionEvent.ACTION_UP:
                isDown = false;
        }
        invalidate();//记得刷新
        return true;
    }
    
    3.绘制
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isDown) {
            canvas.drawCircle(mCurX, mCurY, mBvRadius, mPaint);
        }
    }
    

    三、中级阶段:(放大图片的处理)

    9414344-748958617232b4f3.gif
    放大镜效果1.gif
    9414344-4b3f87e536599a38.png
    放大图平移到触点.png
    1.在onLayout时创建一个rate倍大小的Bitmap
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mBiggerBitmap = createBigBitmap(rate, mFitBitmap);
    }
    
    2.绘制比放大后的图

    这里通过定位,将图片移至指定位置

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (isDown) {
                canvas.drawBitmap(mBiggerBitmap, -mCurX * (rate - 1), -mCurY * (rate - 1), mPaint);
            }
        }
    

    这样效果1就完成了


    3.效果2的实现:

    使用了clipOutPath的API,不须26及以上
    一开始触点是在圆的中心,这里往上调了一下(理由很简单,手指太大,把要看的部位遮住了...)
    但这有个问题,就是最上面的部分再往上就无法显示了,使用做了如下的优化:

    9414344-0e7e2dba8422056e.gif
    优化.gif
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        mShowY = -mCurY * (rate - 1) - 2 * mBvRadius;
        canvas.drawBitmap(mBiggerBitmap,
                -mCurX * (rate - 1), mShowY, mPaint);
        float rY = mCurY > 2 * mBvRadius ? mCurY - 2 * mBvRadius : mCurY +  mBvRadius;
        mPath.addCircle(mCurX, rY, mBvRadius, Path.Direction.CCW);
        canvas.clipOutPath(mPath);
        super.onDraw(canvas);
        canvas.drawCircle(mCurX, rY, mBvRadius, mPaint);
    }
    

    四、高级阶段:优化点:

    1.使用枚举切换放大镜类型:
    enum Style {
        NO_CLIP,//无裁剪,直接放大
        CLIP_CIRCLE,//圆形裁剪
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isDown) {
            switch (mStyle) {
                case NO_CLIP://无裁剪,直接放大
                    float showY = -mCurY * (rate - 1);
                    canvas.drawBitmap(mBiggerBitmap, -mCurX * (rate - 1), showY, mPaint);
                    break;
                case CLIP_CIRCLE:
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        mPath.reset();
                        showY = -mCurY * (rate - 1) - 2 * mBvRadius;
                        canvas.drawBitmap(mBiggerBitmap, -mCurX * (rate - 1), showY, mPaint);
                        float rY = mCurY > 2 * mBvRadius ? mCurY - 2 * mBvRadius : mCurY + mBvRadius;
                        mPath.addCircle(mCurX, rY, mBvRadius, Path.Direction.CCW);
                        canvas.clipOutPath(mPath);
                        super.onDraw(canvas);
                        canvas.drawCircle(mCurX, rY, mBvRadius, mPaint);
                    } else {
                        mStyle = Style.NO_CLIP;//如果版本过低,无裁剪,直接放大
                        invalidate();
                    }
                    //可拓展更多模式....
            }
        }
    }
    
    2.落点在图片边界区域处理:
    9414344-b5d1c7cb2729689a.png
    矩形区域校验.png
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                mCurX = event.getX();
                mCurY = event.getY();
                //校验矩形区域
                isDown = judgeRectArea(mImageW / 2, mImageH / 2, mCurX, mCurY, mImageW, mImageH);
                break;
            case MotionEvent.ACTION_UP:
                isDown = false;
        }
        invalidate();//记得刷新
        return true;
    }
    
    /**
     * 判断落点是否在矩形区域
     */
    public static boolean judgeRectArea(float srcX, float srcY, float dstX, float dstY, float w, float h) {
        return Math.abs(dstX - srcX) < w / 2 && Math.abs(dstY - srcY) < h / 2;
    }
    

    五、上传github并成库

    0.变成库!!,变成库!!,变成库!!
    9414344-58cb802128a63935.png
    变成库.png

    1.上传github
    9414344-0b1c6f12ee035dcb.png
    上传github.png

    2.发布:
    9414344-e54abdaaacdfcddd.png
    1.png
    9414344-d058c5cfcd40a767.png
    2.png

    3.查看:https://jitpack.io/
    9414344-e8b282419b05d06d.png
    see1.png
    4.测试使用:
    9414344-aaff6c5794ddbce4.png
    使用.png

    ok,本篇完结


    后记:捷文规范

    1.本文成长记录及勘误表
    项目源码 日期 备注
    V0.1--github 2018-11-17 Android自定义控件之局部图片放大镜--BiggerView
    2.更多关于我
    笔名 QQ 微信 爱好
    张风捷特烈 1981462002 zdl1994328 语言
    我的github 我的简书 我的掘金 个人网站
    3.声明

    1----本文由张风捷特烈原创,转载请注明
    2----欢迎广大编程爱好者共同交流
    3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
    4----看到这里,我在此感谢你的喜欢与支持


    9414344-8a0c95a090041a0d.png
    icon_wx_200.png
    展开全文
  • 局部放大的多个子图 # -*- coding: utf-8 -*- """ Created on Thu Oct 31 21:17:45 2019 @author: huang """ import xlrd import numpy as np import math import matplotlib.pyplot as plt from matplotlib....
  • 附例:一种对图象进行局部放大的有效方法  在实际工作中,对图象进行局部放大,以便更加清楚、细致的观察图象的某个部位,是经常遇到的问题。在Visual C++6.0中,巧妙、灵活的运用CDC类的StretchBlt()函数以及...
  •  本文主要介绍通过Opencv显示一副图像,同时又可以使用鼠标左键框选局部区域且放大一倍; 1. 使用IplImage的示例代码 # include # include "opencv2/core/core.hpp" # include "opencv2/imgproc/...
  • data 中定义变量: isScale: false, isDrag: false, styles: '', actived: 1, value1: '', limitHourValue: '', hourList: ['11', '12', '13', '14', '17', '18', '19', '20', '21'], // 手指A fingerA: ...
  • 局部自适应图像增强

    千次阅读 2018-09-26 15:03:02
    OpenCv,局部自适应图像增强(Local Adaptive Contrast Enhancement) 转载自:https://blog.csdn.net/EbowTang/article/details/42373081 一、理论  图像增强算法的基本原则是“降低低频区域,突出高频区域”,...
  • qml 在鼠标位置放大图像

    千次阅读 2018-08-16 15:55:06
    首先话不多说,全网找遍了都没有...定义鼠标区域并且去填充显示区域,记住,每次缩放后都需要重新去填充一次才可以 根据鼠标获取到图像的位置,进行最开始和最后的位置计算(这一步是最难的,很多人都是写的很难...
  • 原文地址图片如果不显示:点击这里前言首先分析一下需求:将一个图片显示在屏幕上,并能够对其放大或者平移。用 canvas 画 bitmap 主要有这么几个方法。void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint ...
  • 安卓实现图片放大镜效果

    千次阅读 2018-01-15 17:05:04
    Android实现图片放大镜效果,可以将用于存储图片ID的数组换为动态获取手机照片,从而实现更强大的功能----->图片浏览器
  • 稳定的局部特征检测和描述是很多图像配准和对象识别算法的基本组成部分。Mikolajczyk和Schmid[14]近日评估了不同方法并鉴定SIFT[11]算法是最耐久的一般图像变形算法。本文研究和提高SIFT使用的局部图像描述符。如同...
  • 基于局部均方差的图像局部对比度增强算法 1.基于局部均方差增强原理  我们知道图像的高频部分代表的是图像中类似边缘的高频分量;底频部分代表的是图像中较为平坦的部分。假若用原始图像减去图像中低频部分的,...
  • 一、理论  图像增强算法的基本原则是... 直方均衡化也是一种非常常见的增强方法。但是为了避免背景的干扰,更倾向于采用“局部”方法进行处理。我们这里着重研究自适应对比度增强(ACE)的相关内容。  ACE的定义
  • 简而言之,大多数以前的论文都假设缺失区域是规则的(即中心缺失矩形孔或多个小矩形孔),并且本文提出了局部卷积(PConv)层来处理不规则孔。 1显示了使用建议的PConv的一些修复结果。 看样子还不错,那么 让...
  • 图像直方均衡化和局部增强处理

    万次阅读 2018-04-07 20:10:52
    二使像素值几乎成均匀分布的图像0表示黑,1表示白,中心思想是把原始图像的灰度直方从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布,增加许多图像的局部对比度,亮度可以更好的在直方上分布。...
  • 鼠标滚轮实现图像放大缩小的主要思想:通过wheelEvent来获得鼠标滚轮的angleDelta,即滚轮转角。然后通过数据类型转换,将读取的值转换成整型数值叠加到图像的尺寸长和宽上,从而实现图像的放大和缩小。 注意:滚轮...
  • 我们假定x(i,j)是图像中某点的灰度值,局部区域的定义为:以(i,j)为中心,窗口大小为(2n+1)*(2n+1)的区域,其中n为一个整数。当然这个窗口区域也不一定就要是正方形。局部的平均值,也就是低频部分,可以用下式计算...
  • 点击任意一张图片可以放大预览 需要实现这种效果其实并不难,只要使用下面这个函数就行了 该知识点的官方说明文档链接:点击跳转,需要进一步了解可以点击链接去浏览阅读。 具体实现方法 1、定义图片路径 图片...
  • PhotoSwipe插件官方网站 http://www.photoswipe.com/PhotoSwipe插件能实现手机端点击图片全屏放大 再双击图片放大等功能但有...打开photoswipe.js,大概在3179行有个关于tap的函数定义 在开头先定义一个变量var tap_
  • 图像局部特征(七)--SURF原理总结

    万次阅读 2016-06-13 10:40:24
    一个组代表了逐步放大的滤波模板对同一输入图像进行滤波的一系列响应。每个组又由若干固定的层组成。由于积分图像离散化的原因,两个层之间的最小尺度变化量是由高斯二阶微分滤波器在微分方向上对正负斑点响应长度...
  • 图像的局部对比度增强算法

    千次阅读 2016-01-27 17:14:38
    ...使用局部标准差实现图像的局部对比度增强算法。 Posted on 2013-09-16 15:01 Imageshop 阅读(426) 评论(1) 编辑 收藏  图像的对比度增强算法在很多场合都有着重要的应
  • JavaScript网页特效(一)图片放大

    千次阅读 2017-01-15 15:07:57
    浏览带有图片的购物网站时,有时鼠标放在图片上,可以放大局部看清楚图片。今天要实现的就是这个效果。用到的事件(1)onmouseover:鼠标指针悬浮在指定的对象时发生 (2)onmouseout:鼠标指针离开指定对象时发生 ...
  • 我们假定x(i,j)是图像中某点的灰度值,局部区域的定义为:以(i,j)为中心,窗口大小为(2n+1)*(2n+1)的区域,其中n为一个整数。当然这个窗口区域也不一定就要是正方形。局部的平均值,也就是低频部分,可以用下式计算...
  • 直方均衡(HE)与局部色调映射(LTM)

    千次阅读 2015-08-21 15:04:29
    直方均衡(Histogram Equalization)是图像处理中一个十分基础的概念,具有调整图像灰度,增强对比度的作用。  限制对比度自适应直方均衡(Contrast Limited Adaptive Histogram Equalization,CLAHE),关于该算法的...
  • 之前公司 项目有用到 gps定位 ,以及 工厂地图 布置 点 ,但是 无法使用百度地图之类的 第三方地图SDK ,只给一个工厂平面,就要实现gps定位,一直 地图上布点。 gps 坐标转换到 图片上 的 算法 由 老大 搞定了,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,290
精华内容 8,116
关键字:

局部放大图定义