当前位置: 首页 > 知识库问答 >
问题:

画布降低图像质量

刘博文
2023-03-14

我正在使用画布来修改我的图像。但是,我有一个问题。如果我使用options.inSamplesize=4;图像变得太小,质量下降。但是,如果我不给,它会从内存溢出并给出一个错误。

    protected void onDraw(Canvas canvas) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 1;//Tried 4-But image quality too low


        Bitmap original1 = BitmapFactory.decodeFile(imagePathF, options);

      int width = original1.getWidth();
        int height = original1.getHeight();
        int bounding = dpToPx(Math.round(height));


        float xScale = ((float) bounding) / width2;
        float yScale = ((float) bounding) / height2;
        float scale = (xScale <= yScale) ? xScale : yScale;


        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);


        Bitmap scaledBitmap = Bitmap.createBitmap(original1, 0, 0, width, height, matrix, true);

          Paint paint = new Paint();
        paint.setColor(Color.BLACK); // Text Color
        //Paint alphaChannel = new Paint();
        //alphaChannel.setAlpha(100);
        paint.setAlpha(100);
        paint.setTextSize(20 * scale);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); // Text Overlapping Pattern
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);

        paint.getTextBounds(gText, 0, gText.length(), bounds);
        Typeface font = Typeface.createFromAsset(getAssets(), "Chantelli_Antiqua.ttf");
        paint.setTypeface(font);

        int x = (width2)/2;
        //int y = Math.round(height1)+(Math.round(height1) - Math.round(height2) / 2);
        int y = Math.round(height);
        int yOffset=calcYoff(gText, 0, 0, paint, canvas, Math.round(20 * scale), width);

//位图缩放位图=位图。创建位图(原始1、0、0、宽度、高度、矩阵、真);

              mDrawable = new BitmapDrawable(res, scaledBitmap);//original1);//
          canvas.drawColor(Color.TRANSPARENT);
            //canvas.drawBitmap(resizedBitmap, 0, 0, paint);
            mDrawable.draw(canvas);


            getDrawingCache().compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(imagePathF)));



            super.onDraw(canvas);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            Log.e("Error--------->", e.toString());
        }
    }

这是我当前的错误日志。

11-09 03:21:56.849 12345-12345/com.example.chkee.appfrontE/AndroidRuntime︰致命例外:主进程:com.example.chkee.appfront,PID:12345java.lang.IllegalArgumentExcoop:位图大小超过32位在android.graphics.Bitmap.native创建(本地方法)android.graphics.Bitmap.create位图(Bitmap.java:812)android.graphics.Bitmap.create位图(Bitmap.java:789)android.graphics.Bitmap.create位图(Bitmap.java:720)com.example.chkee.剪贴簿。在android. viewandroid.view.View.draw(View.java:15247)查看. updateDisplayListIfDirty(View. java: 14183)。在android. view查看. getDisplayList(View. java: 14205)。在android. view查看.绘图(View. java: 14975)。在android. view查看集团。绘图儿童(ViewGroup. java: 3406)。在android. view查看集团。调度绘图(ViewGroup. java: 3199)。在android. view上查看. updateDisplayListIfDirty(View. java: 14178)。在android. view上查看. getDisplayList(View. java: 14205)。在android. view上查看. Draw(View. java: 14975)。在android. view上查看组. Draw(ViewGroup. java: 3406)。在android. view上查看组.调度绘制(ViewGroup. java: 3199)。在android. view上查看. updateDisplayListIfDirty(View. java: 14178)。在android. view上查看. getDisplayList(View. java: 14205)。在android. view上查看.绘制(View. java: 14975)。在android. view上查看组. Draw(ViewGroup. java: 3406)。在android. view上查看组.调度绘制(ViewGroup. java: 3199)在android. view上查看. getDisplayList(View. java: 14205)。在android. view上查看.绘图(View. java: 14975)。在android. view上查看组.绘图儿童(ViewGroup. java: 3406)。在android. view上查看组.调度绘图(ViewGroup. java: 3199)。在android. view上查看. updateDisplayListIfDirty(View. java: 14178)。在android. view上查看. getDisplayList(View. java: 14205)。在android. view上查看.绘图(View. java: 14975)。在android. view上查看组.绘图儿童(ViewGroup. java: 3406)。在android. view上查看组.调度绘图(ViewGroup. java: 3199)。在android. widget上查看.绘图(View. java: 15250)。框架布局.绘图(框架PhoneWindow$DecorView. view(PhoneWindow. java: 2906)at android. view. updateDisplayListIfDirty(View. java: 14183)at android. view. getDisplayList(View. java: 14205)at android. view. ThreadedRenderer. updateViewTreeDisplayList(ThreadedRenderer. java: 273)at android. view. ThreadedRenderer. updateRootDisplayList(ThreadedRenderer. java: 279)at android. view. ThreadedRenderer. Draw(ThreadedRenderer. java: 318)at android. view. ViewRootInp. Draw(ViewRootInp. java: 2536)at android. view. ViewRootInp. performDraw(ViewRootInp. java: 2352)at android. view编舞$CallbackRecord. run(Choreograph. java: 767)在android. view。编舞. doCallback(编舞. java: 580)在android. view。编舞. doFrame(编舞. java: 550)在android. view。编舞$FrameDisplayEventReceiver. run(编舞. java: 753)在android. os。Handler. handleCallback(Handler. java: 739)在android. os。Handler。调度消息(Handler. java: 95)在android. os。Loop.循环(Loop. java: 135)在android. app。ActivityThread. main(ActivityThread. java: 5292)在java. lang.反射。方法调用(本地方法)在java. lang.反射。方法调用ZygoteInit. main(ZygoteInit. java: 699)

评论部分展示了我尝试过的更多东西。我也试过了

Bitmap mBackgroundImage = Bitmap.createBitmap(Size, Size,
                Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBackgroundImage);

但是它使我的整个图像变黑,在它上面画画不会影响画布,它仍然是黑色的。

共有2个答案

屈星腾
2023-03-14
  1. 不要创建具有完整高度宽度的位图。尽量减少高度或宽度,而不影响纵横比
  2. 如果inSampleSize=4降低了清晰度,那么选择比这更小的值
  3. 为什么要创建另一个位图缩放位图?如果您真的想创建缩放位图,请尝试bitmap。createScaledBitmap()
  4. 别忘了调用位图。回收()一旦你不需要位图

有关上述各点的更多详细信息,请阅读此处:https://stackoverflow.com/a/33394336/4747587

更新:崩溃不是因为BitmapFactory.decodeFile(),而是因为下面一行代码

 Bitmap scaledBitmap = Bitmap.createBitmap(original1, 0, 0, width, height, matrix, true);

将其替换为:

 Bitmap scaledBitmap= Bitmap.createScaledBitmap(original1, (int)(width/1.5f), (int)(height/1.5f), false); 

因此,请在这里使用1.5f值,选择一个适合您的值。您正在尝试创建一个与全分辨率屏幕大小相同的位图。这需要巨大的内存。相反,你需要创建一个更小的图像。以上链接详细记录了所有这些。

金高飞
2023-03-14

如果你真的想修改你的图像,你可以在运行时修改。使用此链接,您将发现更多详细信息。

运行时调整图像大小时的质量问题

但是,在调整位图大小或缩放位图后,还有另一种方法可以阻止“糟糕的图像质量”。可以使用以下方法禁用从资源加载位图时的缩放:

Options options = new BitmapFactory.Options();
    options.inScaled = false;
    Bitmap source = BitmapFactory.decodeResource(a.getResources(), path, options);

此外,正如#Henry建议的那样,您可以使用:

 Bitmap resizedBitmap = Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, false); 

如何在没有内存异常的情况下根据屏幕大小缩放位图

 类似资料:
  • 我使用html5画布元素在浏览器中调整图像大小。原来质量很低。我发现:当缩放 时禁用插值,但这无助于提高质量。 下面是我的css和js代码,以及用Photoshop缩放和在画布API中缩放的图像。 当在浏览器中缩放图像时,我必须做什么来获得最佳质量? JS: 使用Photoshop调整图像大小: 在画布上调整了图像大小: 下面是我使用2步缩小尺寸的结果: 下面是我使用三步缩小尺寸的结果: 下面是如

  • 谢谢你看。 我在这里尝试做的是...从计算机加载图像(通过使用FileReader),将img标签的src放入文件。然后用那个图像画画布。 问题是当我加载另一个图像文件时。它在画布中加载,但不适合画布大小。它保持原始图像大小,图像的“部分”显示在画布中。 为了解决这个问题,我尝试了以下方法:ctx。drawImage(img,0,0,document.getElementById('canvas'

  • 问题内容: 我正在通过以下代码拍摄照片并将其保存到SD卡中,但是它产生的照片质量如此之低,即使100%的质量也是如此。也许bitmap.compress不是正确的方法(或根本不是位图?!) 这是我的代码: 问题答案: 请调用以下功能从相机捕获图像。 您可以在selectedImageUri变量中获取图像Uri。(图像存储在SD卡中)

  • 我已经开发了一个应用程序来拍摄一张照片并保存在画廊里。我在网上搜索过,我能练习的最简单的方法就是使用。下面是从相机上拍照的代码。注意,我在这个类中使用的是fragment。 获取捕获的图像并将其转换为字符串 我将字符串保存到全局变量中,以便其他活动可以访问它。在另一个活动中,我有一个按钮,通过访问图像字符串将图像保存到文件夹/图库中。 它可以将图像保存到文件夹/图库中......但是图像质量很低.

  • 问题内容: 我需要使用Java程序减小图像的大小(而不是宽度和高度)。他们为此提供了任何好的API吗? 我需要将大小从1MB减少到大约50kb-100 kb。当然,分辨率会降低,但这并不重要。 问题答案: 这是工作代码 这段代码对我来说很棒。如果需要调整图像大小,则可以在此处更改x和y比例J;

  • 我有一个问题。当我试图从相机上拍照时,质量很低。首先,使用摄像头捕捉图片,然后保存到目录中,同时获取图片并显示在我的应用程序中。保存在目录中的图片质量很好,但当我从目录中获取时,质量很低。下面是我的示例代码: 任何解决方案/建议?谢谢:) 解决了的 当我遵循下面Antrromet给出的代码时,问题解决了