【问题标题】:How to load an image from drawable and convert to a bitmap如何从drawable加载图像并转换为位图
【发布时间】:2019-06-30 09:47:05
【问题描述】:

我在可绘制文件夹中有一个图像,我想转换为位图,然后转换为 byte[] 以存储到数据库中,我可以将位图转换为字节数组,但我无法获得由于Bitmap photo = BitmapFactory.decodeResource(getResources(), R.drawable.image); 来自drawable 的图像返回null。怎么做?

我现在有什么

Bitmap photo = BitmapFactory.decodeResource(getResources(), R.drawable.image); //this returns null
if(photo != null)
byte[] bytes = getBitmapAsByteArray(photo);

//this works
DatabaseHelper databaseHelper = new DatabaseHelper(this);
databaseHelper.add("DEFAULT",bytes);

更新: 当我使用photo.setImageBitmap(bitmap); 将位图设置为图像时,它从数据库中检索信息后它没有出现,似乎商店不起作用

我正在像这样将信息存储到数据库中

private static byte[] getBitmapAsByteArray(Bitmap bitmap) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 0, outputStream);
        return outputStream.toByteArray();
    }

public boolean addUserInformation(String username, byte[] picture){
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("USERNAME", username);
        if(picture!=null) {
            values.put("PICTURE", picture);
        }
        id = db.insert(TABLE_NAME1, null, values);
        }
        db.close();
        if(id == -1)
            return false;
        else
            return true;
    }

并检索这样的信息

Cursor data = databaseHelper.getUserInformation();
        if(data.moveToFirst()) {
            mUsername = data.getString(1);
            bytes = data.getBlob(2);
            if(bytes!=null)
                profilePhoto = BitmapFactory.decodeByteArray(bytes, 0, data.getBlob(2).length);
        }

在数据库类中使用 getUserInformation()

public Cursor getUserInformation(){
        SQLiteDatabase db = this.getReadableDatabase();
        String query = "SELECT * FROM " + TABLE_NAME1;
        Cursor c = db.rawQuery(query,null);
        return c;
    }

【问题讨论】:

  • 为什么要将VectorDrawable“转换”为原始像素? VectorDrawable的主要目的是避免光栅化图形,而是使用矢量图形
  • 我需要将图像作为字节数组存储到 SQLite 数据库中
  • 那你为什么要使用VectorDrawable呢?
  • 我应该使用什么来从可绘制文件夹中获取 .xml 图像并将其转换为字节数组? @pskink

标签: java android image bitmap drawable


【解决方案1】:

以下方法应该可以正常工作:

public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
    Drawable drawable = ContextCompat.getDrawable(context, drawableId);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        drawable = (DrawableCompat.wrap(drawable)).mutate();
    }
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);
    return bitmap;
}

build.gradle (project-level)

dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0-alpha5'
    }

build.gradle (app-level)

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.3'
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 23
        vectorDrawables.useSupportLibrary = true
    }
    ...
}
...

或者,您也可以像这样在 Kotlin 中使用 android-ktx,它适用于 Drawable 的任何子类:

build.gradle

dependencies {
    implementation 'androidx.core:core-ktx:1.0.0-alpha1'
}

然后像这样使用Drawable#toBitmap()

val bitmap = AppCompatResources.getDrawable(requireContext(), drawableId).toBitmap() 

【讨论】:

  • 不识别它给我的 BitmapDescriptor 类无法解析符号,我应该导入什么库?
  • @james,然后在此行中使用AppCompatResources 而不是ContextCompatDrawable drawable = AppCompatResources.getDrawable(context, drawableId);
【解决方案2】:

使用这个

Bitmap photo = ((BitmapDrawable) getDrawable(R.drawable.R.drawable.image)).getBitmap();

希望,工作正常;)

【讨论】:

  • 崩溃与 android.graphics.drawable.VectorDrawable 不能转换为 android.graphics.drawable.BitmapDrawable。它还需要 api 级别 21,有没有办法也包含旧的 api?
  • 只有当drawable已经是BitmapDrawable时它才应该工作。在所有其他情况下,当可绘制对象不是BitmapDrawable 时,应该与ClassCastException 一起崩溃,例如VectorDrawableLayerDrawableScaleDrawable
【解决方案3】:

您可以通过非常简单的方式做到这一点。像这样将 Glide 添加到您的项目中 -

implementation 'com.github.bumptech.glide:glide:4.9.0'

然后取一个全局 Bitmap 变量并像这样调用 -

私有位图 imageBitmap;

Glide.with(this)
        .asBitmap()
        .load(R.drawable.image)
        .into(new CustomTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                imageView.setImageBitmap(resource);
                //Save the bitmap to your global bitmap
                imageBitmap = resource;
            }

            @Override
            public void onLoadCleared(@Nullable Drawable placeholder) {
            }
        });

现在将 imageBitmap 传递给您的 getBitmapAsByteArray() 以转换为 byteArray,以便您可以将其保存在 SQLite 数据库中。

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 2019-11-08
    • 1970-01-01
    相关资源
    最近更新 更多