首页 > 解决方案 > 从 MySQL 导入 BLOB 映像的过程中发生错误

问题描述

首先,我将向您展示我的数据库配置。

[MySQL]

create table measurement (
    mnum int not null auto_increment primary key,
    id varchar(50),
    image longblob,
    time int,
    dist double,
    kcal double,
    FOREIGN KEY measurement(id) references user(id)
) default character set utf8 collate utf8_general_ci;

ALTER TABLE measurement auto_increment = 1;

[问题]

首先,我打算将谷歌地图图像放入数据库。所以我研究了如何在 MySQL 中放置一个位图,得到的代码如下。(供您参考,网络库使用了 Retrofit。

[安卓]


        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] bytes = baos.toByteArray();

        mapImage_String = "&image="+ byteArrayToBinaryString(bytes);

    public static String byteArrayToBinaryString(byte[] b) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < b.length; ++i) {
            sb.append(byteToBinaryString(b[i]));
        }
        return sb.toString();
    }

    public static String byteToBinaryString(byte n) {
        StringBuilder sb = new StringBuilder("00000000");
        for (int bit = 0; bit < 8; bit++) {
            if (((n >> bit) & 1) > 0) {
                sb.setCharAt(7 - bit, '1');
            }
        }
        return sb.toString();
    }

[PHP]


        case 'POST' :
            $id = $_POST["id"];
            $image = $_POST["image"];
            $time = $_POST["time"];
            $dist = $_POST["dist"];
            $kcal = $_POST["kcal"];
            
                
            $statement = mysqli_prepare($con, "INSERT INTO measurement(id,image,time,dist,kcal) VALUES (?,?,?,?,?)");   
            mysqli_stmt_bind_param($statement, "ssidd", $id, $image, $time, $dist, $kcal);
            mysqli_stmt_execute($statement);
                
            $response = array();
            $response["success"] = true;
            echo json_encode($response);
            break;

从代码中可以看出,我没有使用 Base64。这样就成功将镜像改成BLOB形式放到MySQL中了。但是,从 MySQL 取回它并不成功。这是获取图片的代码。

[安卓]


    public void setMapImage() {
        Gson gson = new GsonBuilder().setLenient().create();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(MeasureService.MEASURE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        MeasureService retrofitAPI = retrofit.create(MeasureService.class);

        retrofitAPI.getMeasure(userId).enqueue(new Callback<List<Measure>>() {
            @Override
            public void onResponse(Call<List<Measure>> call, Response<List<Measure>> response) {
                // loadingDialog.dismiss();
                if (response.isSuccessful()) { 
                    Log.d("Measure", "Response");
                    List<Measure> data = response.body();

                    if (data.size() > 0) {
                        mapImg = data.get(0).getImage();
                        if (mapImg != "") {
                            Log.d("Measure", "Img ON");
                        }
                       Bitmap bitmap = StringToBitmap(mapImg);
                        mapImage.setImageBitmap(bitmap);
                    }

                } else {
                    Toast.makeText(getApplicationContext(), "No Data.", Toast.LENGTH_LONG).show();
                }

            }

            @Override
            public void onFailure(Call<List<Measure>> call, Throwable t) {
                // loadingDialog.dismiss();
                Toast.makeText(getApplicationContext(), "No Network.", Toast.LENGTH_LONG).show();
                t.printStackTrace();
            }
        });
    }

    public byte[] binaryStringToByteArray(String s) {
        int count = s.length() / 8;
        byte[] b = new byte[count];
        for (int i = 1; i < count; ++i) {
            String t = s.substring((i - 1) * 8, i * 8);
            b[i - 1] = binaryStringToByte(t);
        }
        return b;
    }

    public byte binaryStringToByte(String s) {
        byte ret = 0, total = 0;
        for (int i = 0; i < 8; ++i) {
            ret = (s.charAt(7 - i) == '1') ? (byte) (1 << i) : 0;
            total = (byte) (ret | total);
        }
        return total;

    }

    public Bitmap StringToBitmap(String ImageString) {
        try {
            byte[] bytes = binaryStringToByteArray(ImageString);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            Bitmap bitmap = BitmapFactory.decodeStream(bais);
            return bitmap;
        } catch (Exception e) {
            e.getMessage();
            return null;
        }
    }

[PHP]

        case 'GET' :
            $id = $_GET["id"];
            
            $statement = mysqli_prepare($con, "select * from measurement where id = ?");
            mysqli_stmt_bind_param($statement, "s", $id);
            mysqli_stmt_execute($statement);

            mysqli_stmt_store_result($statement);
            mysqli_stmt_bind_result($statement, $mnum, $id, $image, $time, $dist, $kcal);

            $response = array();
            $response["success"] = false;
            $result = array();

            while(mysqli_stmt_fetch($statement)){
            $response["success"] = true;
            $response["mnum"] = $mnum;
            $response["id"] = $id;
            $response["image"] = $image;
            $response["time"] = $time;
            $response["dist"] = $dist;
            $response["kcal"] = $kcal;
            array_push($result, array(
                "success"=>$response["success"], 
                "mnum" => $response["fnum"],
                "id" => $response["id"],
                "image" => $response["image"],
                "time" => $response["time"],
                "dist" => $response["dist"],  
                "kcal" => $response["kcal"]));
            }
            echo json_encode($result);
            break;

执行此代码时,日志中会出现以下语法。

D/skia: --- Failed to create image decoder with message 'unimplemented'

我认为 PHP 应该给出一些设置。但我不确定要提供哪些设置。

标签: phpandroidmysql

解决方案


推荐阅读