精华内容
下载资源
问答
  • 如何实现一个循环显示超长图片的控件

    千次阅读 热门讨论 2016-06-16 18:59:45
    某次被问到如何实现一个滚筒状的控件,就是可以将一张很长的图片沿着Y轴无限旋转,如下图所示: 大概就是这个意思,当时还不知道图片可以裁剪,想不出整个流程怎么搞,后来得知Bitmap有裁剪功能,才想到这个功能...

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

    某次被问到如何实现一个滚筒状的控件,就是可以将一张很长的图片沿着Y轴无限旋转,如下图所示:

    大概就是这个意思,当时还不知道图片可以裁剪,想不出整个流程怎么搞,后来得知Bitmap有裁剪功能,才想到这个功能怎么实现,花了一下午时间整了一下有了成果。
    这是这张长图:

    然后旋转起来就是这个样子:

    上面这个效果在实际运行过程中是非常流畅的,这张图片是按照每秒几帧截的,所以看起来一顿一顿的。

    先来说说如何实现:

    第一次:先按照屏幕的宽度截取这张长图的起始部分。
    第二次:以偏移量开始,重复第一次的行为。

    最后:当这张图片的结尾部分不足以支撑整个屏幕的宽度时,先截取这张图片的末尾部分,绘制。然后再以剩余的宽度截取图片的头部部分,绘制。依次进行,直至重新回到第一次。

    /**
     * Created by shangbin on 2016/6/16.
     * Email: sahadev@foxmail.com
     */
    public class CylinderImageView extends View {
        //用于裁剪的原始图片资源
        private Bitmap mSourceBitmap = null;
    
        // 图片的高宽
        private int mBitmapHeight, mBitmapWidth;
    
        // 移动单位,每次移动多少个单位
        private final int mMoveUnit = 1;
    
        // 图片整体移动的偏移量
        private int xOffset = 0;
    
        private Bitmap mPointerA, mPointerB;// 用于持有两张拼接图片的引用,并释放原先的图片资源
    
        /**
         * 循环滚动标志位
         */
        private boolean mRunningFlag;
    
        private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 0) {
                    invalidate();
                }
            }
        };
    
        public CylinderImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initVideoView();
        }
    
        public CylinderImageView(Context context) {
            super(context);
            initVideoView();
        }
    
        public CylinderImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            initVideoView();
        }
    
        private void initVideoView() {
            // 获取需要循环展示的图片的高宽
            mSourceBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.android_m_hero_1200);
            mBitmapHeight = mSourceBitmap.getHeight();
            mBitmapWidth = mSourceBitmap.getWidth();
    
            mRunningFlag = true;
    
            setFocusableInTouchMode(true);
            requestFocus();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            // 简单设置一下控件的宽高,这里的高度以图片的高度为准
            setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(mBitmapHeight, MeasureSpec.getMode(heightMeasureSpec)));
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            recycleTmpBitmap();
    
            final int left = getLeft();
            final int top = getTop();
            final int right = getRight();
            final int bottom = getBottom();
    
            // 计算图片的高度
            int height = bottom - top;
            // 第一张图的宽带
            int tempWidth = right - left;
    
            // 如果一张图片轮播完,则从头开始
            if (xOffset >= mBitmapWidth) {
                xOffset = 0;
            }
    
            // 重新计算截取的图的宽度
            tempWidth = xOffset + tempWidth >= mBitmapWidth ? mBitmapWidth - xOffset : tempWidth;
    
            mPointerA = Bitmap
                    .createBitmap(mSourceBitmap, xOffset, 0, tempWidth, height > mBitmapHeight ? mBitmapHeight : height);
    
            Paint bitmapPaint = new Paint();
    
            // 绘制这张图
            canvas.drawBitmap(mPointerA, getMatrix(), bitmapPaint);
    
            // 如果最后的图片已经不足以填充整个屏幕,则截取图片的头部以连接上尾部,形成一个闭环
            if (tempWidth < right - left) {
                Rect dst = new Rect(tempWidth, 0, right, mBitmapHeight);
                mPointerB = Bitmap.createBitmap(mSourceBitmap, 0, 0, right - left - tempWidth,
                        height > mBitmapHeight ? mBitmapHeight : height);
                // 将另一张图片绘制在这张图片的后半部分
                canvas.drawBitmap(mPointerB, null, dst, bitmapPaint);
            }
    
            // 累计图片的偏移量
            xOffset += mMoveUnit;
    
            //由handler的延迟发送产生绘制间隔
            if (mRunningFlag) {
                mHandler.sendEmptyMessageDelayed(0, 1);
            }
        }
    
        /**
         * 回收临时图像
         */
        private void recycleTmpBitmap() {
            if (mPointerA != null) {
                mPointerA.recycle();
                mPointerA = null;
            }
    
            if (mPointerB != null) {
                mPointerB.recycle();
                mPointerB = null;
            }
        }
    
        /**
         * 恢复
         */
        public void resume() {
            mRunningFlag = true;
            invalidate();
        }
    
        /**
         * 暂停
         */
        public void pause() {
            mRunningFlag = false;
        }
    
        /**
         * 回收清理工作
         */
        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            pause();
            recycleTmpBitmap();
            mSourceBitmap.recycle();
        }
    }
    

    以上是CylinderImageView的实现代码。

    其中有两个公开方法:
    resume() 用于在Activity的onResume()中调用,以便恢复旋转。
    pause() 用于在Activiyt的onPause()中调用,以便暂停旋转。

    下面是使用示例:

    public class MainActivity extends AppCompatActivity {
        private CylinderImageView cylinderImageView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            cylinderImageView = (CylinderImageView) findViewById(R.id.cylinderImageView);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
    
            cylinderImageView.resume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
    
            cylinderImageView.pause();
        }
    }

    因为这个控件内部涉及大量的图片操作,所以大伙一定很关心内存的使用。我为此专门做了内存测试,结果内存占用非常小:

    这张图是没有使用CylinderImageView时应用程序所占用的内存:17.9MB:

    我这里所使用的示例图片的长宽是1200x353,也就是说它被加载到内存中所占用的内存大小是1200x353x4/1024/1024=1.61MB.

    再加上在屏幕上所显示的Bitmap所占用的内存为:1080x353x4/1024/1024=1.45MB.(这里的1080是我的屏幕宽度,在屏幕上显示的图片占了整个屏幕的宽度,所以是1080)

    因为内存回收并不是实时的,所以在内存使用最高峰时,所使用的内存=17.9+1.61+1.45x2=22.43.

    实际的运行占用内存为:


    上面两张图片的差距是图片内存回收的差值,但是这里的高峰内存值与我们计算的内存值有些差距,这是因为除了内存之外,我们还在XML布局文件中声明了控件以及加载控件也占用了一定的内存空间。

    调用pause()方法的内存状况:

    调用resume()方法的内存状况:


    Activity销毁之后所占用的内存:

    通过上面一系列图示说明这个控件将内存的消耗控制在了合理的范围之内,没有滥用内存。

    最后,大功告成,不知道是否明白我说的呢?

    相关Demo演示请参见:https://github.com/sahadev/CylinderImageView

    展开全文
  • 如何用pycharm和face_recognition来识别一张图片中的多张人脸,并且将其标志出来 博主之前在做python课程设计的时候,想做一个人脸识别的入门教程,于是自己网上找了些资料,发现用Python加上face_recognition来做...

    如何用pycharm和face_recognition来识别一张图片中的多张人脸,并且将其标志出来

    博主之前在做python课程设计的时候,想做一个人脸识别的入门教程,于是自己网上找了些资料,发现用Python加上face_recognition来做人脸识别,非常简单就能实现一些人脸识别常用的功能,例如标志处图片中的每张人脸下面这样:
    在这里插入图片描述

    要实现上面这个功能其实很简单,但首先你要装好face_recognition库,具体安装方法可以自行百度,下面讲讲实现步骤:

    开始前的准备工作:
    将你要识别的图片放到你pycharm目前的工作目录中

    1. 首先肯定要先导入要使用的库

    import face_recognition
    
    from PIL import Image, ImageDraw
    

    导入Image和ImageDraw是为了方便在已识别的人脸上画出标志框

    2.导入图片,对图片中人脸上的面部特征位置进行定位,并获取人脸的数目

    #将图像载入的一个numpy array类型上,函数括号内填你的目标图片文件名
    image = face_recognition.load_image_file('alot.jpg')
    
    #给定一个图像,返回图像中每个人脸的面部特征位置(眼睛、鼻子等),返回值是一个元组列表,列表中的每个元组包含每张人脸的人脸位置——(top, right, bottom, left)
    locations = face_recognition.face_locations(image)
    
    #用一个变量保存人脸数目
    a=len(locations)
    

    3.对图片中的每张人脸进行标志画框

    #循环的次数就是人脸的个数,for循环作用相当于在上一次标志人脸的图片上标志下一张人脸
    for i in range(0, a):
        
        #由于每次循环只能标志一张人脸,所以要重复载入上次保存的图片
        image = face_recognition.load_image_file('alot.jpg')
       
        #对第i张人脸进行标志
        pos = locations[i]
       
        #要想在指定图片上绘制图像,要先将指定图片转换为一个可绘制对象
        #首先将要进行绘图的图像转换为array
        pil_image = Image.fromarray(image)
        #再用ImageDraw模块的一个函数—Draw,创建一个给定图像上绘图的对象
        d = ImageDraw.Draw(pil_image, 'RGBA')
        
        #rectangle是ImageDraw的一个成员方法,作用是在图像的指定位置绘制一个长方形,前两个表示一个坐标,后两个表示一个坐标
        #坐标(pos[3],pos[0])表示人脸的左上角,坐标(pos[1],pos[2])表示人脸的右下角
        d.rectangle((pos[3], pos[0], pos[1], pos[2]))
        
        #每次标志完人脸后要保存
        pil_image.save("alot.jpg")
    #将已经标志好人脸的图片展示在屏幕前
    pil_image.show( )
    

    通过上述代码就可标志一张图片上的多张人脸,但是用到的是for循环,而且每次循环都要保存和载入图片,如果人脸数目过多的话,运行速度势必会变慢,不知道大家有什么更好的方法,欢迎在评论区说出你的想法~

    展开全文
  • 最近做的项目,要用到滑动切换的效果,就是类似新闻客户端的图片一张一张的自动切换或者手动滑动切换,于是就搜集了一下资料,使用两种方式实现这样的效果,分别是ViewFlipper和ViewPager。这两种方式都比较容易的...

    最近做的项目,要用到滑动切换的效果,就是类似新闻客户端的图片一张一张的自动切换或者手动滑动切换,于是就搜集了一下资料,使用两种方式实现这样的效果,分别是ViewFlipper和ViewPager。这两种方式都比较容易的实现了手势滑动,但是ViewFlipper更容易实现循环滑动切换。

    啥都先不说了,看看效果图


    下面我们赶快进去到代码里面去吧!

    1.     ViewFlipper是继承至FrameLayout的,所以它是一个Layout里面可以放置多个View。实现两种样式,第一种样式.类似新闻客户端中图片自动手动滑动切换 ,第二种样式.整个布局手动滑动切换 接下来就分别实现这两种样式,

    第一种样式.类似新闻客户端中图片自动手动滑动切换


    第二种样式.整个布局手动滑动切换


    2.     ViewPager用于实现多页面的切换效果,该类存在于Google的兼容包里面,所以在引用时记得在BuilldPath中加入“android-support-v4.jar”,这里还是实现了两种样式的滑动,类似新闻客户端中图片自动手动滑动切换和整个布局手动滑动切换接下来就具体看看是如何实现这两种样式,

    第一种样式.类似新闻客户端中图片自动手动滑动切换


    第二种样式.整个布局手动滑动切换


    以上就是具体实现滑动切换的主类,Demo里面用到的布局、图片资源都放在下载里面去了,用到的朋友欢迎下载!第一次写博客,有许多问题,望大家见谅。有什么问题请留言!

    PS 在实际的项目中可能会遇到滑动的界面里面有ScrollView,那按照上面的方法,左右滑动和上下滑动就冲突了,

    解决办法如下:首先自定义一个ScrollView


    接着定义一个界面类MyViewFlipperThird

    ps:代码下载地址

    展开全文
  • 一、再次膜拜下RetrofitRetrofit无论从性能还是使用方便性上都很屌...二、概念介绍1)注解@Multipart从字面上理解就是与多媒体文件相关的,没错,图片、文件等的上传都要用到该注解,其中每个部分需要使用@Part来注解。

    本文代码详见:https://github.com/honghailiang/RetrofitUpLoadImage

    一、再次膜拜下Retrofit

    Retrofit无论从性能还是使用方便性上都很屌!!!,本文不去介绍其运作原理(虽然很想搞明白),后面会出专题文章解析Retrofit的内部原理;本文只是从使用上解析Retrofit实现多图片/文件、图文上传的功能。文件上传相关可参考Multipart/form-data文件上传简介 Apache FileUpload文件上传功能


    二、概念介绍

    1)注解@Multipart

    从字面上理解就是与多媒体文件相关的,没错,图片、文件等的上传都要用到该注解,其中每个部分需要使用@Part来注解。。看其注释

    /**
     * Denotes that the request body is multi-part. Parts should be declared as parameters and
     * annotated with {@link Part @Part}.
     */

    2)注解@PartMap

    当然可以理解为使用@PartMap注释,传递多个Part,以实现多文件上传。注释

    /**
     * Denotes name and value parts of a multi-part request.
     * <p>
     * Values of the map on which this annotation exists will be processed in one of two ways:
     * <ul>
     * <li>If the type is {@link okhttp3.RequestBody RequestBody} the value will be used
     * directly with its content type.</li>
     * <li>Other object types will be converted to an appropriate representation by using
     * {@linkplain Converter a converter}.</li>
     * </ul>
     * <p>
     * <pre><code>
     * @Multipart
     * @POST("/upload")
     * Call<ResponseBody> upload(
     *     @Part("file") RequestBody file,
     *     @PartMap Map<String, RequestBody> params);
     * </code></pre>
     * <p>
     * A {@code null} value for the map, as a key, or as a value is not allowed.
     *
     * @see Multipart
     * @see Part
     */

    3)RequestBody

    从上面注释中就可以看到参数类型是RequestBody,其就是请求体。文件上传就需要参数为RequestBody。官方使用说明如下http://square.github.io/retrofit/

    Multipart parts use one of Retrofit's converters or they can implement RequestBody to handle their own serialization.


    四、基本实现

    了解了以上概念,下面就一一实现

    1)接口定义

    public interface IHttpService {
    @Multipart
        @POST("file/upLoad.do")
        Call<BaseBean> upLoadAgree(@PartMap Map<String, RequestBody>params);
    }

    BaseBean是根据服务端返回数据进行定义的,这个使用时可以根据自有Server定义。

    2)Retrofit实现

    /**
     * Created by DELL on 2017/3/16.
     * 上传文件用(包含图片)
     */
    
    public class RetrofitHttpUpLoad {
        /**
         * 超时时间60s
         */
        private static final long DEFAULT_TIMEOUT = 60;
        private volatile static RetrofitHttpUpLoad mInstance;
        public Retrofit mRetrofit;
        public IHttpService mHttpService;
        private static Map<String, RequestBody> params;
    
        private RetrofitHttpUpLoad() {
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(UrlConfig.ROOT_URL)
                    .client(genericClient())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            mHttpService = mRetrofit.create(IHttpService.class);
        }
    
        public static RetrofitHttpUpLoad getInstance() {
            if (mInstance == null) {
                synchronized (RetrofitHttpUpLoad.class) {
                    if (mInstance == null)
                        mInstance = new RetrofitHttpUpLoad();
                    params = new HashMap<String, RequestBody>();
                }
            }
            return mInstance;
        }
    
        /**
         * 添加统一超时时间,http日志打印
         *
         * @return
         */
        private OkHttpClient genericClient() {
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            OkHttpClient httpClient = new OkHttpClient.Builder()
                    .addInterceptor(logging)
                    .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                    .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                    .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                    .build();
            return httpClient;
        }
    
    
        /**
         * 将call加入队列并实现回调
         *
         * @param call             调入的call
         * @param retrofitCallBack 回调
         * @param method           调用方法标志,回调用
         * @param <T>              泛型参数
         */
        public <T> void addToEnqueue(Call<T> call, final RetrofitCallBack retrofitCallBack, final int method) {
            final Context context = MyApplication.getContext();
            call.enqueue(new Callback<T>() {
                @Override
                public void onResponse(Call<T> call, Response<T> response) {
                    LogUtil.d("retrofit back code ====" + response.code());
                    if (null != response.body()) {
                        if (response.code() == 200) {
                            LogUtil.d("retrofit back body ====" + new Gson().toJson(response.body()));
                            retrofitCallBack.onResponse(response, method);
                        } else {
                            LogUtil.d("toEnqueue, onResponse Fail:" + response.code());
                            ToastUtil.makeShortText(context, "网络连接错误" + response.code());
                            retrofitCallBack.onFailure(response, method);
                        }
                    } else {
                        LogUtil.d("toEnqueue, onResponse Fail m:" + response.message());
                        ToastUtil.makeShortText(context, "网络连接错误" + response.message());
                        retrofitCallBack.onFailure(response, method);
                    }
                }
    
                @Override
                public void onFailure(Call<T> call, Throwable t) {
                    LogUtil.d("toEnqueue, onResponse Fail unKnown:" + t.getMessage());
                    t.printStackTrace();
                    ToastUtil.makeShortText(context, "网络连接错误" + t.getMessage());
                    retrofitCallBack.onFailure(null, method);
                }
            });
        }
    
        /**
         * 添加参数
         * 根据传进来的Object对象来判断是String还是File类型的参数
         */
        public RetrofitHttpUpLoad addParameter(String key, Object o) {
    
            if (o instanceof String) {
                RequestBody body = RequestBody.create(MediaType.parse("text/plain;charset=UTF-8"), (String) o);
                params.put(key, body);
            } else if (o instanceof File) {
                RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data;charset=UTF-8"), (File) o);
                params.put(key + "\"; filename=\"" + ((File) o).getName() + "", body);
            }
            return this;
        }
    
        /**
         * 构建RequestBody
         */
        public Map<String, RequestBody> bulider() {
    
            return params;
        }
    
        public void clear(){
            params.clear();
        }
    }


    其中定义了Retrofit实例、还用拦截器定义了统一的超时时间和日志打印;将call加入队列并实现回调。最重要的就是添加参数:

     /**
         * 添加参数
         * 根据传进来的Object对象来判断是String还是File类型的参数
         */
        public RetrofitHttpUpLoad addParameter(String key, Object o) {
    
            if (o instanceof String) {
                RequestBody body = RequestBody.create(MediaType.parse("text/plain;charset=UTF-8"), (String) o);
                params.put(key, body);
            } else if (o instanceof File) {
                RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data;charset=UTF-8"), (File) o);
                params.put(key + "\"; filename=\"" + ((File) o).getName() + "", body);
            }
            return this;
        }


    这里就是根据传入的参数,返回不同的RequestBody, 注意文件的key值。


    3)使用

    private void upLoadAgree() {
            showWaitDialog();
            RetrofitHttpUpLoad retrofitHttpUpLoad = RetrofitHttpUpLoad.getInstance();
            retrofitHttpUpLoad.clear();
            if (!StringUtil.isEmpty(pathImage[0])){
                retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("pic1",new File(pathImage[0]));
            }
            if (!StringUtil.isEmpty(pathImage[1])){
                retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("pic2", new File(pathImage[1]));
            }
            if (!StringUtil.isEmpty(pathImage[2])){
                retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("zip", new File(pathImage[2]));
            }
    
            Map<String, RequestBody> params = retrofitHttpUpLoad
                    .addParameter("status", "4")
                    .addParameter("pickupId", tv_orderquality_pid.getText().toString())
                    .addParameter("cause", reason)
                    .addParameter("connectname", et_orderquality_lxrname.getText().toString())
                    .addParameter("connectphone", et_orderquality_lxrphone.getText().toString())
                    .addParameter("details", et_orderquality_xqms.getText().toString())
                    .bulider();
            retrofitHttpUpLoad.addToEnqueue(retrofitHttpUpLoad.mHttpService.upLoadAgree(params),
                    this, HttpStaticApi.HTTP_UPLOADAGREE);
        }



    需要注意的是要对图片及文件路径进行判空操作,否则会报异常W/System.err: java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)


    五、报文日志

    其中图片报文有省略

    D/OkHttp: --> POST http://192.168.xxx.xxx:8880/xxx/nocheck/file/agree.do http/1.1
    D/OkHttp: Content-Type: multipart/form-data; boundary=f3e7369a-ead9-46e2-9ddd-448442fd5108
    D/OkHttp: Content-Length: 300580
    D/OkHttp: --f3e7369a-ead9-46e2-9ddd-448442fd5108
    D/OkHttp: Content-Disposition: form-data; name="pic2"; filename="90079.jpg"
    D/OkHttp: Content-Transfer-Encoding: binary
    D/OkHttp: Content-Type: multipart/form-data;charset=UTF-8
    D/OkHttp: Content-Length: 149456
    D/OkHttp: ??????JFIF????H??H????????C??		
    D/OkHttp: 	"##!  %*5-%'2(  .?/279<<<$-BFA:F5;<9????C
    D/OkHttp: 9& &99999999999999999999999999999999999999999999999999?????8"????????????????????????????????????????????????????????????????????|???/n?s??y?]8ug?7?R??????h?tΘa?T?T<?U???z???+3C?w??tdf??=<??????fN??s??x??hhzd??X~?X??i?{~/?<^??~=zX??\??4?U?ɡ)I???????????????????$??@??? iM?"J?R	2?f?MK5x#w?????r?I?3?Y??l???V?Bj??>{??t?u????]????g>?o??o???dM?U??????J?R??<?+?;??????????OG>????=?5?L?9?&???_/\?yu??~|*,???My?r????????='?d?=?t*??*?Y??(????????????????	YB i?Jlv??d?"l????Y??4??X?7???;??sY?\κ+?N??;?L??&?(?MJ???@w~~???a?qs??m7??y???Ns?\?C?g??>???N%??N??gs?Q??c????Z?t???x??{??^_}s?s??gO?????N?|}?;??y?y?ǎ|?v??N?l???????????*k5?(?????????1$?B??j?+,?l???hN??U?<sgb?g?x?S??;;c?,??7?0Z?J?I?r??X?9?t?'\?1W+
    D/OkHttp: [?? ????=/X???n??T*4?u??<?????s?q??????c???\?6?YV?p????oB%??|?s??????????{??g??k?}?t??d{]^W???v?WB?x???|z9?>V?{ǒ>?o??Y????xk?k7???{w????b?!JQjRQ%RH?%8?H??Q??Ys?{???u??(?`?b\??k?cC:u#???d?C??&??W.CXd?e??N??n????.?%v?,.zW?>??&??+??r??S'?.n?[	V?	?q??oGL?,:?S??????/?o<???,?B???;??????^[?#Lm??7.Q?6sONz??fwN?
    D/OkHttp: ???,?\????
    D/OkHttp: ???U<???1?Z???=??pn?~q??[-?P??=?j?va?R?	??4X*???nv?H??j?j?p??`h#-???qiA?U?????x?&v?b?R??o?.??H[M5??Y??5?>%Y?j????x?2.m??=??GG???
    D/OkHttp: \?D??(?JK9<J???JE?jl??pW
    D/OkHttp: ??}??i?6??R??:!J??FT?!e???
    D/OkHttp: ????:??5????%??`?|???;z?G??[?P???N=???T??X?-?okNe???Y??f8?`:?P???x?1?I?g	?0?)?fe*P?qU?~?jSY%??gɡR?(?$A?|y?}??s?2?<?/??4?s??@-?,??AZ?az?,??bl?.??WD??????q?X?u}?+G?z?h8=?w[`?j??g&q?c????????<|??|? 1????q^???
    D/OkHttp: 5??)x???:*dK??|?KPz5v?4?+?>eO?4??i?P2F?&\9???? -V?esf~&F?Q??S?\???8{??*B?1qVO????-S??!?????????*6??
    D/OkHttp: 3?5W?r?x??+?\?r???6??C??Ms,H?AE??=q??????(??f?=,????Z??+????L??<??v_i-?m|????6??L???=?4?Y?{?W??9=??\AW???~??{@!?^ Z6??,?k>|??C
    D/OkHttp: aZ??-?ы??R?K???1?6`'??F%/4wZ?Cn????[?]?el??U&[???1db-4????????~er!?4??>ji?]??AV?[v??e??`θo???帏!(??Pk?XCI??Glk-p??p	?B?b???ae???d?]-|"??*??`??l??Tmn`???
    D/OkHttp: R?G??h?DETp???i???^????u?E??1?wW%?<????????3e??V????	**m??9V??O?R??f?b?
    D/OkHttp: ??j%)^?$??g?\?Qm^`??
    D/OkHttp: ?	?[*?\?@/T@,?|@\$F?????v_??uA???:?9>%B????1 =?D]{?"??*^??q1??i??B?bs?L_???? e??W?2??pDR?Q??M?? ?{????7S?????Dzcb\??????0?????u? h???e??7X??)?s{??DIqf???QdM??V?????r??MTk?=??+?>b0?b???i?\?lI??H?P??,?Pn[]??.?`.X?=A?I?P?@?<~??Px??.???9?(??:=??5E?n?!l??? 5???ee_??'[????p?d??1?)g?s<????kop?вd?19m?ft??ab????????j?5/pT?M?xBb??8???z??????wX??V??|~x????????c?Rsx???D???ixH??ud?50??MΘ7???<?^I???i?`?????f?A?????????;?U?H????a~?W臸?@O?'u\-???????CN,????-???@?+"n?:y???G	|S??C?F5?????Ix?????)?????b	22???jRj????j?,K?K"¥</?G?w/	*?W????sn??L????n?n????? k????"?*??~?9??<4?,c?d>?EG??iB??0+??i?Y??D???p???????S|.?2???# &??"v?Y??P??O?#EK???,J?6U?>a???;?-rM??@???^b??@??K?????PI??4?qM|??V??h[Ld??R????or?U?M??)_?J?^S?41n}?@n|??
    D/OkHttp: --f3e7369a-ead9-46e2-9ddd-448442fd5108
    D/OkHttp: Content-Disposition: form-data; name="cause"
    D/OkHttp: Content-Transfer-Encoding: binary
    D/OkHttp: Content-Type: text/plain;charset=UTF-8
    D/OkHttp: Content-Length: 33
    D/OkHttp: 对货物数量、质量有异议
    D/OkHttp: --f3e7369a-ead9-46e2-9ddd-448442fd5108
    D/OkHttp: Content-Disposition: form-data; name="details"
    D/OkHttp: Content-Transfer-Encoding: binary
    D/OkHttp: Content-Type: text/plain;charset=UTF-8
    D/OkHttp: Content-Length: 9
    D/OkHttp: 哈哈哈
    D/OkHttp: --f3e7369a-ead9-46e2-9ddd-448442fd5108
    D/OkHttp: Content-Disposition: form-data; name="status"
    D/OkHttp: Content-Transfer-Encoding: binary
    D/OkHttp: Content-Type: text/plain;charset=UTF-8
    D/OkHttp: Content-Length: 1
    D/OkHttp: 4
    D/OkHttp: --f3e7369a-ead9-46e2-9ddd-448442fd5108
    D/OkHttp: Content-Disposition: form-data; name="pickupId"
    D/OkHttp: Content-Transfer-Encoding: binary
    D/OkHttp: Content-Type: text/plain;charset=UTF-8
    D/OkHttp: Content-Length: 6
    D/OkHttp: 105329
    D/OkHttp: --f3e7369a-ead9-46e2-9ddd-448442fd5108
    D/OkHttp: Content-Disposition: form-data; name="connectphone"
    D/OkHttp: Content-Transfer-Encoding: binary
    D/OkHttp: Content-Type: text/plain;charset=UTF-8
    D/OkHttp: Content-Length: 11
    D/OkHttp: 13xxxxxxxxx
    D/OkHttp: --f3e7369a-ead9-46e2-9ddd-448442fd5108
    D/OkHttp: Content-Disposition: form-data; name="connectname"
    D/OkHttp: Content-Transfer-Encoding: binary
    D/OkHttp: Content-Type: text/plain;charset=UTF-8
    D/OkHttp: Content-Length: 3
    D/OkHttp: 111
    D/OkHttp: --f3e7369a-ead9-46e2-9ddd-448442fd5108--
    D/OkHttp: --> END POST (300580-byte body)


    六、代码托管

    https://github.com/honghailiang/RetrofitUpLoadImage


    七、效果图:


    八、服务端代码

    FileItemFactory factory = new DiskFileItemFactory();
    		ServletFileUpload upload = new ServletFileUpload(factory);
    		File directory = null;
    		List<FileItem> items = new ArrayList<FileItem>();
    
    		InputStream is = null;
    
    		FileOutputStream fos = null;
    		
    
    		try {
    			items = upload.parseRequest(request);
    			// 得到所有的文件
    			Iterator<FileItem> it = items.iterator();
    			while (it.hasNext()) {
    				FileItem fItem = (FileItem) it.next();
    				String fName = "";
    				Object fValue = null;
    				if (fItem.isFormField()) { // 普通文本框的值
    					fName = fItem.getFieldName();
    					fValue = fItem.getString("UTF-8");
    					
    					if("pickupId".equals(fName)){
    						pickupAppeal.setPickupId(fValue.toString());
    					}else if("cause".equals(fName)){
    						pickupAppeal.setCause(fValue.toString());
    					}else if("connectname".equals(fName)){
    						pickupAppeal.setConnectname(fValue.toString());
    					}else if("connectphone".equals(fName)){
    						pickupAppeal.setConnectphone(fValue.toString());
    					}else if("details".equals(fName)){
    						pickupAppeal.setDetails(fValue.toString());
    					}else if("status".equals(fName)){
    						String status = fValue.toString();
    						BigDecimal big = new BigDecimal(status);
    						pickupAppeal.setStatus(big);
    					}
    					
    					//map.put(fName, fValue);
    				} else { // 获取上传文件的值
    					fName = fItem.getFieldName();
    					fValue = fItem.getInputStream();
    					String name = fItem.getName();
    					if (name != null && !("".equals(name))) {
    						name = name.substring(name.lastIndexOf(File.separator) + 1);
    						int lenN =name.indexOf(".");
    						String suf = name.substring(lenN, name.length());
    						
    						String day = DateUtil.format(Calendar.getInstance().getTime(), 
    								"yyyy-MM-dd");
    						String path = PATH+File.separator+day;
    						directory = new File(path);
    						if (!directory.exists()) {
    							directory.mkdirs();
    						}
    
    						String preFile =UUID.randomUUID().toString().replace("-", "");
    						
    						String filePath = path + File.separator+preFile+suf;
    						String serverPath = day+ File.separator+preFile+suf;
    						map.put(fName,  serverPath);
    						map.put(fName+"m", name);
    						is = fItem.getInputStream();
    						fos = new FileOutputStream(filePath);
    						byte[] buffer = new byte[1024];
    						int len = 0;
    						while ((len = is.read(buffer, 0, 1024)) != -1) {
    							fos.write(buffer, 0, len);
    						}
    						fos.flush();
    
    					}
    				}
    			}
    		} catch (Exception e) {
    			pLog.error("接收参数错误:" + e.getMessage());
    			resultInfo.setStatus(ComStatus.RESULTINFO_STATUS_FAILE);
    			resultInfo.setMessage(ComStatus.RESULTINFO_MESSAGE_FAILE);
    			
    			resultInfo.setData(map);
    			resReslt.setResData(resultInfo);
    		} finally {
    			try {
    				if (null != fos) {
    					fos.close();
    				}
    
    				if (null != is) {
    					is.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}






    
    
    
    展开全文
  • 使用TensorFlow识别交通标志

    万次阅读 2017-08-10 21:36:07
    Abdulla写的使用TensorFlow识别交通标志,作者已经授权翻译,这是原文。 我看到了速度限制标志,但只是没有看见你 这是使用深度学习模型去识别交通标志的第一部分。本系列的目的是学习如何使用深度...
  • Opencv3+VS2017实现交通标志检测

    千次阅读 2018-05-31 09:43:51
    可靠的交通标志检测是对其进行准确识别的前提,本次作业首先利用交通标志的红色特征域分割出潜在的交通标志区域,然后通过中值滤波、腐蚀、膨胀与填充操作,初步抑制目标图像的噪声,分割出交通标志独立的图像元素,...
  • Python中while循环的基本用法

    万次阅读 多人点赞 2019-09-11 10:21:34
    while和for都可以使程序重复执行某一段代码(又称作循环体),区别是for循环用于针对集合中的每一个元素都一个代码块,而while循环在表达式为True的情况下会不断地执行,直到指定条件不满足为止。 今天我们一起来...
  • 相信一部分车主拿了新车,用户手册也没怎么碰过,到了大冬天,才发现汽车空调怎么开暖气,甚至连暖风开关标志也不清楚是哪个,那么今天小编就带你们去看看。 很简单,暖气开关标志一般显示为一个“温度计”,或者...
  • yolov3交通标志识别练习

    千次阅读 2020-01-19 20:41:53
    如何快速、准确地定位图片或是视频中的交通标志,受到了许多研究人员的关注。 ##2. 数据集分析 本次课程实验基于6000余张实景照片,标注其中所有的交通标志,实际 分类为5类。实际训练数据为实际场景下的照片,具备...
  • JPEG是网络中使用非常频繁的一种图片,本身是一种有损压缩格式,本文并不对其压缩和编码进行研究,只是对JPEG的文件存储格式进行浅析,然后说明在C#中实现对其存储数据的解析。 JPEG是按段存储的,在真正的图像数据...
  • 面部区域的面部标志索引在dlib内部实现的面部标志性检测器产生映射到特定面部结构的68(x,y)坐标。这些68点映射是通过在标记的iBUG 300-W数据集上训练一个形状预测器获得的。下面我们可以看到这68个坐标映射到的每...
  • ViewPager循环滑动及自动播放

    千次阅读 2016-02-15 16:29:23
    就不能继续往下滑动了,从用户的角度来看,这点的体验很不好,用户可能期待的是当我滑动到最后一页的时候,可以继续滑动,并滑动到第一页,所以我们需要实现viewpager的循环滑动。在网上也找了很多例子,基本上比较...
  • VGA系列之一:VGA显示网络图片

    万次阅读 多人点赞 2017-06-17 21:21:39
    VGA系列之一:VGA显示网络图片VGA系列之一VGA显示网络图片 1 如何用FPGA实现VGA显示 2 网络图片和VGA显示有何区别 3VGA如何显示图片
  • png图片解码

    万次阅读 2015-07-18 02:43:26
    PNG文件标志 PNG数据块 … PNG数据块 所以我们可以看到-x里面png格式的判断函数: bool Image::isPng(const unsigned char * data, ssize_t dataLen) { if (dataLen ) { return false; } ...
  • 问题描述: 因为埋点的需要,需要判断一个产品是否进入...为什么会出现这种情况啊,明明是在componentDidMount中做的处理,该生命周期函数运行的时候不是页面dom都加载完了吗,那不应该获取不到图片高度啊? 是不是...
  • gif 格式图片详细解析

    万次阅读 2018-01-21 20:01:36
    一个GIF文件可以包含多幅图象,一幅图象结束之后紧接着下是一幅图象的标识符,图象标识符以0x2C(‘,’)字符开始,定义紧接着它的图象的性质,包括图象相对于逻辑屏幕边界的偏移量、图象大小以及有无局部颜色列表和...
  • PNG,JPEG,BMP,JIF图片格式详解及其对比

    万次阅读 2016-08-25 00:19:52
    图片格式详解不知道大家有没有注意过网页里,手机里,平板里的图片,事实上,图片格式多样,不同平台对不同格式的图片支持也不一样,所以需要根据不同场合,使用不同格式的图片。一.PNG格式便携式网络图形(Portable...
  • Android 性能优化(十)图片加载和大图片缓存机制OOM完美解决方案LruCache&DiskLruCache ... Android List,Set,Ma...
  • 爬取今日头条图片

    千次阅读 2017-03-04 11:49:41
    这时我们可以看到许多带有图片的文章。当我们滑动到页面底部时,网页会通过ajax加载更多文章。2、打开浏览器F12的开发者工具,点击Network(chrome下)选项,尝试加载更多文章,可以看到如下http请求: 我们可以...
  • libev 中IO事件循环解析

    千次阅读 2016-10-24 09:56:06
    先了解 struct ANFD,ANFD表示事件循环中对一个文件描述符fd的监视的基本信息结构体,定义如下: typedef struct { WL head; //watch_list结构体 unsigned char events; /* 所监视的事件 */ ...
  • ffmpeg命令操作 合并视频 取图片帧数 1.获取视频图片 ffmpeg -i input.mp4 -r 15 -q:v 2 -f image2 img_%04d.jpeg -r 是获取每秒视频帧数 -q:v是图片质量 2 2.图像合并为视频 ffmpeg -threads 2 -y -r 15 -i ...
  • 无线循环的可自动滚动播放轮播图

    千次阅读 2015-04-14 11:33:41
    最近从网上找了一些轮播图的源码,但是发现多少都有一点小问题,就找了一个近乎完美的,稍微修改了一下,本文只是对源码进行了一些修改,修改了在触摸到图片并拖动图片的时候会继续滚动的问题,和在拖动一小下之后返回了上...
  • GIF图片数据格式

    千次阅读 2013-11-01 15:56:50
    一个GIF文件可以包含多幅图象,一幅图象结束之后紧接着下是一幅图象的标识符,图象标识符以0x2C(',')字符开始,定义紧接着它的图象的性质,包括图象相对于逻辑屏幕边界的偏移量、图象大小以及有无局部颜色列表和...
  • ESP8266+STM32F407+OV7670实现图片传输

    万次阅读 多人点赞 2020-04-29 10:10:14
       声明:由于ESP8266与STM32之间采用串口进行通讯,导致传输速率较低,一到两秒才可以传输一帧图片,因此无法实现实时的图像显示。   本文虽然以串口通讯的方式进行数据传输,但是建议想要实现实时视频显示的...
  • 图片文件格式汇编

    千次阅读 2014-02-23 17:06:13
    BMP文件格式 BMP文件格式 6.1 BMP文件格式 6.1.1 简介 位图文件(Bitmap-File,BMP)格式是Windows采用的图像文件存储格式,在Windows环境下运行的所有图像处理软件都支持这种格式。Windows 3.0以前的BMP位图...
  • 实际上为了有效地创造黑白素描图,你真正需要的是一些模糊和两张图片的混合技术,叫做dodging and burning. 用OpenCV、Python一张RGB颜色的图像经过下面四个步骤就能够生成出一张素描图: 将RGB图转化为灰度图。 ...
  • 从(1)和(2)中,两种刷新差别,仅仅在于方法(1)会更改ViewHolder的标志,共同点都会调用requestLayout(),导致RecyclerView 重新测量和布局,到此还是看不出闪烁问题的原因所在。另外还有一个重要实验未说:...
  • VS2015 + Halcon18 - (一) MFC加载图片&打开相机

    千次阅读 热门讨论 2019-05-28 10:04:43
    一个正经的目录前言1、加载图片1.1、代码片段合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,911
精华内容 11,164
关键字:

内循环标志图片