手写简单的图片加载框架

今天翻看旧文件的时候不经意间看到了以前写的图片加载文件,所以拿出来重新理一理。

思路:请求图片优先级:内存缓存》本地缓存》网络

给imageView设置图片的方法:

根据图片请求优先级来,

 /**
     *
     * @param imageView 设置图片的控件
     * @param context 上下文
     * @param url 图片资源路径
     */
    public static void setBitmapFromCache(ImageView imageView,Context context,String url){
        if(TextUtils.isEmpty(url)){
            return;
        }
        Bitmap bitmap=null;
        //先从内存缓存中查找图片资源
        bitmap=getBitmapFromMemoryCache(url);
        if(bitmap!=null){
            imageView.setImageBitmap(bitmap);
            return;
        }
        //再从应用的缓存目录中查找图片
        bitmap=getBitmapFormFileCache(context,url);
        if(bitmap!=null){
            imageView.setImageBitmap(bitmap);
            return;
        }
        //再从网络上去异步请求
        getBitmapAsyncLoad(imageView,url,context);
    }


然后分别看一下三个请求方法的具体实现:

1.内存缓存:

//从内存缓存中获取bitmap
    private static Bitmap getBitmapFromMemoryCache(String url) {
        Bitmap bitmap=null;
        if(url!=null){
            bitmap=lruCache.get(url);
        }
        return bitmap;
    }


2.本地缓存:

//从文件缓存(应用的缓存目录)获得数据
    private static Bitmap getBitmapFormFileCache(Context context,String url) {
        Bitmap bitmap=null;
        String fileName= url.substring(url.lastIndexOf("/")+1);//只截取最后一级文件名,如:sdcard/pics/demo.jpg截取后-->>demo.jpg
        //获得应用的缓存目录
        File cacheDir=context.getCacheDir();
        if(cacheDir!=null){
            File[] files=cacheDir.listFiles();
            for(int i=0;i<files.length;i++){
                if(files[i].getName().equals(fileName)){
                    bitmap=BitmapFactory.decodeFile(files[i].getAbsolutePath());
                    return bitmap;
                }
            }
        }
        return bitmap;
    }


3.从网络请求图片资源,并在请求成功后将bitmap分别存入内存缓存和本地缓存中:

使用基础网络请求框架HttpURLConnection和异步任务AsyncTask实现异步网络请求:

 private static void getBitmapAsyncLoad(ImageView imageView, String url,Context context) {
        MyAsyncTask task=new MyAsyncTask(context, imageView);
        task.execute(url);
    }

    static class  MyAsyncTask extends AsyncTask<String, Void, Bitmap>{
        Context context;
        ImageView imageView=null;
        public MyAsyncTask(Context context,ImageView imageview) {
            this.context=context;
            this.imageView_header=imageview;
        }
        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap bitmap=null;
            String  path=params[0];
            try {
                URL url=new URL(path);
                HttpURLConnection connection=(HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(5000);
                connection.setRequestMethod("GET");
                connection.setDoInput(true);

                if(connection.getResponseCode()==200){
                    InputStream inputStream= connection.getInputStream();
                    //把返回的图片资源按比例缩放处理
                    bitmap=compressBitmap(inputStream);
                    //存入缓存
                    if(bitmap!=null){
                        //放到内存缓存中
                        lruCache.put(path, bitmap);
                        //放到应用缓存中
                        bitmapCacheFile(bitmap,path,context);
                    }
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bitmap;
        }


        @Override
        protected void onPostExecute(Bitmap result) {
            imageView.setImageBitmap(result);
            super.onPostExecute(result);
        }

其中用到的图片压缩方法:

private Bitmap  compressBitmap(InputStream inputStream) {
            byte[] datas=getBytesFromStream(inputStream);
            BitmapFactory.Options options=new BitmapFactory.Options();
            //对二进制数据解码时仅做图片的边界处理
            options.inJustDecodeBounds=true;

            BitmapFactory.decodeByteArray(datas, 0, datas.length, options);
            //边界的宽高
            int outWidth=options.outWidth;
            int outHeight=options.outHeight;

            int targetWidth=70;
            int targetHeight=70;

            int wbl=outWidth/targetWidth;
            int hbl=outHeight/targetHeight;

            int bl=wbl>hbl?wbl:hbl;
            if(bl<0){
                bl=1;
            }
            options.inSampleSize=bl;
            options.inJustDecodeBounds=false;

            Bitmap bitmap=BitmapFactory.decodeByteArray(datas, 0, datas.length, options);
            return bitmap;
        }

//从输入流提取字节数组

private static  byte[] getBytesFromStream(InputStream inputStream){
        byte[] datas=null;
        try{
        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
        
        byte[] buffer=new byte[1024];
        int len=0;
        while((len=inputStream.read(buffer))!=-1){
            outputStream.write(buffer, 0, len);
        }
        datas=outputStream.toByteArray();
        outputStream.close();
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return datas;
    }

网络请求成功后将bitmap存入本地的方法:

private void bitmapCacheFile(Bitmap bitmap, String path,Context context) throws FileNotFoundException {
            File cacheFile=context.getCacheDir();
            if(!cacheFile.exists()){
                cacheFile.mkdirs();
            }
            String fileName=path.substring(path.lastIndexOf("/")+1);
            File file=new File(cacheFile,fileName);
            OutputStream stream=new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        }


最后别忘了加上内存缓存设置:
    static LruCache<String, Bitmap> lruCache=null;
    static{
        int maxsize=4*1024*1024;
        lruCache=new LruCache<String, Bitmap>(maxsize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes()*value.getHeight();
            }
        };
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的卷积神经网络模型,用于数字图片识别问题。 首先,我们需要导入必要的库和数据集: ```python import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers from tensorflow.keras.datasets import mnist # MNIST 数据集 (x_train, y_train), (x_test, y_test) = mnist.load_data() # 将像素值缩放到 [0, 1] 范围内 x_train = x_train.astype("float32") / 255.0 x_test = x_test.astype("float32") / 255.0 # 将标签转换为 one-hot 编码 y_train = tf.one_hot(y_train, depth=10) y_test = tf.one_hot(y_test, depth=10) # 将数据集转换为 TensorFlow Dataset 对象 train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test)) # 打乱训练集并分批次 train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64) ``` 然后,我们定义卷积神经网络模型: ```python model = keras.Sequential( [ layers.Input(shape=(28, 28, 1)), layers.Conv2D(32, kernel_size=(3, 3), activation="relu"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Conv2D(64, kernel_size=(3, 3), activation="relu"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Flatten(), layers.Dropout(0.5), layers.Dense(10, activation="softmax"), ] ) ``` 这个模型包含两个卷积层和两个池化层,以及一个全连接层和一个输出层。我们使用了 `ReLU` 激活函数和 `softmax` 输出层。 最后,我们编译模型并开始训练: ```python model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"]) model.fit(train_dataset, epochs=10, validation_data=test_dataset) ``` 这个模型在训练集上的准确率可以达到 99% 左右,在测试集上的准确率可以达到 98% 左右。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值