首页 > 解决方案 > 无法将过滤后的图像保存到外部存储android

问题描述

我根本不是 Java 人。在使用react-native-vision-camera时,我需要创建自己的帧处理器。该帧处理器将简单地在每一帧上应用一些 opengl 过滤器并返回保存过滤图像的路径。这是我到目前为止所写的,其中大部分都是从这里和那里复制来满足我的需要的。

package com.story;

import android.util.*;
import android.content.Context;
import android.os.Environment;
import java.lang.String;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.lang.System;
import java.lang.StringBuilder;
import java.io.FileOutputStream;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.*;
import java.text.SimpleDateFormat;

import androidx.camera.core.ImageProxy;
import android.media.Image;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import org.wysaid.common.Common;
import org.wysaid.common.SharedContext;
import org.wysaid.myUtils.FileUtil;
import org.wysaid.myUtils.ImageUtil;
import org.wysaid.myUtils.MsgUtil;
import org.wysaid.nativePort.CGEImageHandler;
import org.wysaid.nativePort.CGENativeLibrary;

import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin;
import org.jetbrains.annotations.NotNull;

public class FrameEffectPlugin extends FrameProcessorPlugin {

    public static String status = "";

    private Bitmap convertImageProxyToBitmap(ImageProxy image) {
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);
        return BitmapFactory.decodeByteArray(bytes,0,bytes.length,null);
    }

    public String saveBitmap(Bitmap finalBitmap, String fname) {
        String root = Environment.getExternalStorageDirectory().toString();
        File myDir = new File(root + "/cache-images");
        if(!myDir.exists() || !myDir.isDirectory()){
            myDir.mkdirs();
        }

        File file = new File(myDir, fname);
        if (file.exists()) file.delete ();
        try {
            FileOutputStream out = new FileOutputStream(file);
            finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            status = "exception while saving bitmap";
            e.printStackTrace();
        }

        return file.getAbsolutePath();
    }

    @Override
    public Object callback(@NotNull ImageProxy image, Object[] params) {
        Bitmap bitmapImg = convertImageProxyToBitmap(image);
        String ruleString = "@adjust hsl 0.02 -0.31 -0.17";

        Bitmap dstImage = CGENativeLibrary.filterImage_MultipleEffects(bitmapImg, ruleString, 1.0f);
        String timeStamp = System.currentTimeMillis() + "";
        String fname = "storyCache_"+ timeStamp +".jpg";
        String path = saveBitmap(dstImage, fname);

        WritableNativeMap map = new WritableNativeMap();
        map.putString("path", path);
        map.putString("status", status);
        return map;
    }

    FrameEffectPlugin() {
        super("addFrameEffect");
    }
}

它总是说exception while saving bitmap作为状态。如果我尝试使用返回的路径以本机反应方式渲染图像,它不会显示任何内容(这实际上应该发生)。

在这一点上,我认为问题出在convertImageProxyToBitmap()功能上。它无法生成位图,因此库(gpuimage-plus)无法应用过滤器。所以,图像没有被保存。

但我是这个领域的菜鸟,所以我不知道接下来要修复/做什么。请帮我解决这个问题:(

标签: javaandroid

解决方案


推荐阅读