色度抠图之取色

最近做音视频项目中的色度抠图功能,用吸管进行当前帧取色,然后进行强度和阴影调节进行取色,具体效果可查看剪映的色度抠图功能。
这篇文章就讲述了如何对视频当前帧的某个位置进行取色。

首先需要获取视频对应的当前帧:

  /**
     * 获取当前帧对应的Bitmap
     *
     * @param clip     媒体片段对象
     * @param position 当前位置
     * @return
     */
    private Bitmap getCurrentBitmap(MediaClip clip, long position) {
        File file = new File(clip.getFilePath());
        if (!file.exists()) return null;

        if (clip.isVideo()) {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(file.getAbsolutePath());
            return retriever.getFrameAtTime(position, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
        } else {
            return BitmapFactory.decodeFile(file.getAbsolutePath());
        }
    }

然后从获取到的Bitmap上取触摸位置的颜色:

   /**
     * 从Bitmap指定点获取颜色
     *
     * @param bitmap 源图
     * @param wRatio 水平方向位置在整个帧图位置上的比例
     * @param hRatio 垂直方向位置在整个帧图位置上的比例
     * @return
     */
    public int getColorFromBitmap(Bitmap bitmap, float wRatio, float hRatio) {
        if (bitmap == null || bitmap.isRecycled()) {
            return 0;
        }

        Rect sampleRect = new Rect();
        final int sampleWidth = 10;
        final int sampleHeight = 10;
        sampleRect.left = (int) (bitmap.getWidth() * wRatio);
        if (sampleRect.left < sampleWidth / 2) {
            sampleRect.left = 0;
        } else if (sampleRect.left + sampleWidth > bitmap.getWidth()) {
            sampleRect.left = bitmap.getWidth() - sampleWidth;
        } else {
            sampleRect.left = sampleRect.left - sampleWidth / 2;
        }

        sampleRect.top = (int) (bitmap.getHeight() * hRatio);
        if (sampleRect.top < sampleHeight / 2) {
            sampleRect.top = 0;
        } else if (sampleRect.top + sampleHeight > bitmap.getHeight()) {
            sampleRect.top = bitmap.getHeight() - sampleHeight;
        } else {
            sampleRect.top = sampleRect.top - sampleHeight / 2;
        }

        sampleRect.right = sampleRect.left + sampleWidth;
        sampleRect.bottom = sampleRect.top + sampleHeight;

        int[] pixels = new int[sampleWidth * sampleHeight];
        bitmap.getPixels(pixels, 0, sampleWidth, sampleRect.left, sampleRect.top, sampleWidth, sampleHeight);
        float a = 0;
        float r = 0;
        float g = 0;
        float b = 0;
        for (int px : pixels) {
            a = a + Color.alpha(px);
            r = r + Color.red(px);
            g = g + Color.green(px);
            b = b + Color.blue(px);
        }
        a = 1;
        r = r / pixels.length / 256;
        g = g / pixels.length / 256;
        b = b / pixels.length / 256;
        return Color.argb(a, r, g, b);
    }

主要方法:public void getPixels(@ColorInt int[] pixels, int offset, int stride,
int x, int y, int width, int height)

引申方法:public void copyPixelsToBuffer(Buffer dst)

感谢大家的支持,如有错误请指正,如需转载请标明原文出处!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值