【问题标题】:resizing the canvas dimensions and size of a bitmap file调整位图文件的画布尺寸和大小
【发布时间】:2014-06-03 12:54:48
【问题描述】:

我的应用程序正在尝试从矩形外部存储调整 PNG 文件的大小:(例如 1000 w x 2000 h)

我们的目标是将其变成 256 x 256 的图像,方法是在图像的两侧添加空白区域,使其现在为 2000 x 2000,然后将其缩小到 256x256,从而使其成为正方形而不拉伸原始图像.

我认为我可以很聪明并使用ImageView 来执行此操作并添加缩放到屏幕的图像预览,但我因空指针而崩溃......

我的调整大小方法

private void  resizeImage(String fileName){
        ImageView tempImageView = new ImageView(this);
        tempImageView.setDrawingCacheEnabled(true);
        tempImageView.setLayoutParams(new LayoutParams(256, 256));
        tempImageView.setScaleType(ScaleType.CENTER_INSIDE);
        Bitmap bm = BitmapFactory.decodeFile(getKingNozzleStorageDirectory()+fileName);
        tempImageView.setImageBitmap(bm);
        rootView.addView(tempImageView);
        tempImageView.buildDrawingCache();
        Bitmap resized_bm = tempImageView.getDrawingCache();

        FileOutputStream outStream;

        try {
            outStream = new FileOutputStream(getKingNozzleStorageDirectory() + "new"+fileName );

            try {
                resized_bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
                outStream.flush();
                outStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

我遇到的异常:

06-03 08:43:50.006: W/System.err(3842): java.lang.NullPointerException 06-03 08:43:50.006: W/System.err(3842): 在 com.eliddell.kingnozzle.activities.KNDrawingActivity.resizeImage(KNDrawingActivity.java:285) 06-03 08:43:50.006: W/System.err(3842): 在 com.eliddell.kingnozzle.activities.KNDrawingActivity.onClick(KNDrawingActivity.java:223) 06-03 08:43:50.006: W/System.err(3842): 在 android.view.View.performClick(View.java:4438) 06-03 08:43:50.006: W / System.err(3842):在 android.view.View$PerformClick.run(View.java:18422) 06-03 08:43:50.006:W/System.err(3842):在 android.os.Handler.handleCallback(Handler.java:733) 06-03 08:43:50.006:W/System.err(3842):在 android.os.Handler.dispatchMessage(Handler.java:95) 06-03 08:43:50.006:W/System.err(3842):在 android.os.Looper.loop(Looper.java:136) 06-03 08:43:50.006: W / System.err(3842):在 android.app.ActivityThread.main(ActivityThread.java:5017) 06-03 08:43:50.006:W/System.err(3842):在 java.lang.reflect.Method.invokeNative(Native Method) 06-03 08:43:50.006:W/System.err(3842):在 java.lang.reflect.Method.invoke(Method.java:515) 06-03 08:43:50.006: W / System.err(3842):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 06-03 08:43:50.006: W/System.err(3842): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 06-03 08:43:50.006:W/System.err(3842):在 dalvik.system.NativeStart.main(Native Method)

如果我注释掉以下行

resized_bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);

它没有崩溃,这让我相信 resize_bm 没有被创建?

Bitmap resized_bm = tempImageView.getDrawingCache();

显然,可能还有其他方法可以实现我的画布调整大小,所以当然欢迎这些见解.. 但是有人知道我做错了什么吗?

我没有看到任何将画布填充添加到位图宽度的本地方法..

【问题讨论】:

    标签: android android-file android-bitmap


    【解决方案1】:

    我认为你没有在这一行创建Bitmap

    Bitmap resized_bm = tempImageView.getDrawingCache();
    

    您需要对 ImageView 进行更多修改。试试这个:

        tempImageView.setDrawingCacheEnabled(true);
    
        // resize and create canvas
        tempImageView.measure(MeasureSpec.makeMeasureSpec(256, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(256, MeasureSpec.EXACTLY));
        tempImageView.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); 
    
        tempImageView.buildDrawingCache(true);
        final Bitmap resized_bm = tempImageView.getDrawingCache();
        tempImageView.setDrawingCacheEnabled(false);
    

    更新:

    为什么不使用标准方法?

    final Bitmap bitmap = Bitmap.createBitmap(256, 256, Config.ARGB_8888);
    final Canvas canvas = new Canvas(bitmap);
    final Bitmap tmp = BitmapFactory.decodeFile(getKingNozzleStorageDirectory() + fileName);
    final int width = (int) (1f * tmp.getWidth() / tmp.getHeight() * 256);
    final int height = 256;
    final Bitmap scaled = Bitmap.createScaledBitmap(tmp, width, height, false);
    final int leftOffset = (bitmap.getWidth() - scaled.getWidth()) / 2;
    final int topOffset = 0;
    canvas.drawBitmap(scaled, leftOffset, topOffset, null);
    

    更新 2:

    如果你想使用 ImageView,这可能很奇怪,但这段代码对我有用:

    final ImageView tempImageView = new ImageView(getActivity());
    final Bitmap tmp = BitmapFactory.decodeFile(LayoutParams.WRAP_CONTENT);
    tempImageView.setImageBitmap(tmp);
    tempImageView.setDrawingCacheEnabled(true);
    
    // resize and create canvas
    tempImageView.measure(MeasureSpec.makeMeasureSpec(256, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(256, MeasureSpec.EXACTLY));
    tempImageView.layout(0, 0, tempImageView.getMeasuredWidth(), tempImageView.getMeasuredHeight()); 
    
    tempImageView.buildDrawingCache(true);
    final Bitmap resized_bm = Bitmap.createBitmap(tempImageView.getDrawingCache());
    tempImageView.setDrawingCacheEnabled(false);
    

    【讨论】:

    • 很好奇,准备试试这个,但是为什么又把绘图缓存启用设置为false呢?
    • 用于清除绘图缓存。 developer.android.com/intl/ru/reference/android/view/…在完成位图工作后清除它是一个好方法。
    • 好的,我试过这个..但仍然得到相同的结果..它实际上是在写一个文件,它只是空的..
    • 最终位图位图 = Bitmap.createBitmap(256, 256, null);抛出一个空指针
    • 抱歉没有完整检查代码。我在最后一行 int width = tmp.getWidth() / tmp.getHeight() * 256; 处有另一个错误;我修复它并更新我的答案。
    猜你喜欢
    • 2021-12-15
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 2011-08-22
    • 2018-02-05
    • 2012-12-16
    • 1970-01-01
    • 2018-10-26
    相关资源
    最近更新 更多