【问题标题】:Color Matrix for Image Sharpening in androidandroid中图像锐化的颜色矩阵
【发布时间】:2015-12-09 09:25:21
【问题描述】:

我有一个使用颜色矩阵在 ImageView 上添加图像效果的类。我有几个用于对比度、曝光、温度和饱和度的颜色矩阵。 例如:

public static Bitmap changeContrast(Bitmap bmp, float contrast)
{
    ColorMatrix cm = new ColorMatrix(new float[]
            {
                    contrast, 0, 0, 0, 0,
                    0, contrast, 0, 0, 0,
                    0, 0, contrast, 0, 0,
                    0, 0, 0, 1, 0
            });

    return getBitmapFromColorMatrix(cm, bmp);
}

现在我的问题是图像的锐化。这些似乎没有颜色矩阵。请帮忙。

我尝试使用here 中的代码锐化图像,但处理时间太长,而且我不知道应该将哪些有效值传递给sharpenImage(Bitmap src, double weight) 方法的权重参数。

【问题讨论】:

    标签: android matrix colormatrix image-effects


    【解决方案1】:

    可能为时已晚,但我只是想分享一种快速锐化图像的方法。

     public static Bitmap doSharpen(Bitmap original, float[] radius) {  
          Bitmap bitmap = Bitmap.createBitmap(
                  original.getWidth(), original.getHeight(),
                  Bitmap.Config.ARGB_8888);
    
              RenderScript rs = RenderScript.create(yourContext);
    
              Allocation allocIn = Allocation.createFromBitmap(rs, original);
              Allocation allocOut = Allocation.createFromBitmap(rs, bitmap);
    
              ScriptIntrinsicConvolve3x3 convolution
                  = ScriptIntrinsicConvolve3x3.create(rs, Element.U8_4(rs));
              convolution.setInput(allocIn);
              convolution.setCoefficients(radius);
              convolution.forEach(allocOut);
    
              allocOut.copyTo(bitmap);       
              rs.destroy();   
    
              return bitmap;                   
    
    }
    

    这是我创建的 3 种不同的锐化类型:

    // low
    private static void loadBitmapSharp() {
        float[] sharp = { -0.60f, -0.60f, -0.60f, -0.60f, 5.81f, -0.60f,
                -0.60f, -0.60f, -0.60f };
    //you call the method above and just paste the bitmap you want to apply it and the float of above
        yourbitmap = doSharpen(getbitmap, sharp));
    }
    
    // medium
    private static void loadBitmapSharp1() {
        float[] sharp = { 0.0f, -1.0f, 0.0f, -1.0f, 5.0f, -1.0f, 0.0f, -1.0f,
                0.0f
    
        }; 
    //you call the method above and just paste the bitmap you want to apply it and the float of above
        yourbitmap = doSharpen(getbitmap, sharp));
    }
    
    // high
    private static void loadBitmapSharp2() {
        float[] sharp = { -0.15f, -0.15f, -0.15f, -0.15f, 2.2f, -0.15f, -0.15f,
                -0.15f, -0.15f
        };
     //you call the method above and just paste the bitmap you want to apply it and the float of above
        yourbitmap = doSharpen(getbitmap, sharp));
    }
    

    您也可以将它们直接应用到没有空白的位图上,它快速简单,效果很好!

    【讨论】:

    • 如何根据滑块值改变矩阵值?
    【解决方案2】:

    在这里改进第一个答案,添加一个搜索栏(滑块)来改变图像的清晰度。

    public Bitmap doSharpen(Bitmap original, float multiplier) {
        float[] sharp = { 0, -multiplier, 0, -multiplier, 5f*multiplier, -multiplier, 0, -multiplier, 0};
        Bitmap bitmap = Bitmap.createBitmap(
                original.getWidth(), original.getHeight(),
                Bitmap.Config.ARGB_8888);
    
        RenderScript rs = RenderScript.create(MainActivity.this);
    
        Allocation allocIn = Allocation.createFromBitmap(rs, original);
        Allocation allocOut = Allocation.createFromBitmap(rs, bitmap);
    
        ScriptIntrinsicConvolve3x3 convolution
                = ScriptIntrinsicConvolve3x3.create(rs, Element.U8_4(rs));
        convolution.setInput(allocIn);
        convolution.setCoefficients(sharp);
        convolution.forEach(allocOut);
    
        allocOut.copyTo(bitmap);
        rs.destroy();
    
        return bitmap;
    
    }
    

    我不得不根据我的项目对其进行一些修改。我没有在方法中使用卷积矩阵,而是在方法中声明了它。我们将取而代之的是 seekbar 的 changed 变量。

    sharpnessSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                Bitmap sharpenedBitmap = doSharpen(btmp,(float)i);
                imageV.setImageBitmap(sharpenedBitmap);
            }
    

    在 setOnSeekBarChangeListener 中,我们得到改变后的值,即 int i 并使用 doSharpen 方法传递它,以便可以在 doSharpen() 方法中定义的卷积矩阵中使用它。

    【讨论】:

      【解决方案3】:

      这是我用搜索栏用于色温的值。 (你让他们对我提出的一个问题发表评论)

      public static Bitmap doTemperature(Bitmap bmp, float temp){
      
           ColorMatrix cm = new ColorMatrix(new float[]
                   {
                   1, 0, 0, temp, 0,
                   0, 1, 0, temp/2, 0,
                   0, 0, 1, temp/4, 0,
                   0, 0, 0, 1, 0
      
                   });
      
           Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
           Canvas canvas = new Canvas(ret);
           Paint paint = new Paint();
           paint.setColorFilter(new ColorMatrixColorFilter(cm));
           canvas.drawBitmap(bmp, 0, 0, paint);
           return ret;
       }
      //you call it with this method
      private void loadBitmapTemp() {
          //private Seekbar temp_value; 
          temp_value = (SeekBar) findViewById(R.id.temp_value);
          temp_value.setMax(100);
          temp_value.setProgress(50);
      
          int progressTemp = temp_value.getProgress();
          progressTemp -= 50;
          float temp = (float) progressTemp / 220;
          progress_text.setVisibility(View.VISIBLE);
          progress_text.setText(" " + progressTemp * 2);
          yourBitmap = doTemperature(getbitmap, temp));
      }
      

      【讨论】:

        猜你喜欢
        • 2017-05-17
        • 1970-01-01
        • 1970-01-01
        • 2011-10-22
        • 1970-01-01
        • 1970-01-01
        • 2016-08-17
        • 2016-02-15
        • 2015-03-28
        相关资源
        最近更新 更多