【问题标题】:LIBGDX, ANDROID: deadlock killing app when when returning captured pictureLIBGDX,ANDROID:返回捕获的图片时死锁杀死应用程序
【发布时间】:2016-05-19 12:35:50
【问题描述】:

过去两三天我一直在尝试构建一个程序,允许用户使用原生相机拍照从图库中挑选一张 .之后,从任一方法获取图片,图片返回核心 libgdx 项目进行处理。从画廊中挑选作品就像一种魅力。而 拍照 方法,如果以缩略图形式返回,则效果很好。

但是,我想使用调整大小的照片而不是缩略图。该应用程序不断崩溃并出现“AndroidGraphics:死锁杀死”错误。代码胜于雄辩。

public void takePicture() {
    selectedImagePath = null;
    selectedByteArray = null;

    /* when thumbnail
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if(intent.resolveActivity(getPackageManager())!=null) {
        startActivityForResult(intent, SELECT_TAKEPICTURE_CODE);
    }
    */

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = timeStamp + ".jpg";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    pictureImagePath = storageDir.getAbsolutePath() + "/" + imageFileName;
    File file = new File(pictureImagePath);
    Uri outputFileUri = Uri.fromFile(file);
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
    startActivityForResult(cameraIntent, SELECT_TAKEPICTURE_CODE);
}

处理活动。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(resultCode==RESULT_CANCELED||data==null) {
        didUserCancel = true;
    }

    /* Also for the thumbnail use
    if (requestCode == SELECT_TAKEPICTURE_CODE&&resultCode==RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");
        selectedByteArray = convertBitmapToByteArray(imageBitmap);
    }
    */

    if (requestCode == SELECT_TAKEPICTURE_CODE&&resultCode==RESULT_OK) {
        File imgFile = new File(pictureImagePath);
        if (imgFile.exists()) {
            pictureCaptured = true;
        }
    }
}

三个辅助方法

private Bitmap scaleDownBitmap(Bitmap realImage, float maxImageSize, boolean filter) {
    float ratio = Math.min( maxImageSize / (float)realImage.getWidth(),
            maxImageSize / (float)realImage.getHeight());
    int width = Math.round( ratio * (float)realImage.getWidth());
    int height = Math.round( ratio * (float)realImage.getHeight());
    Bitmap newBitmap = Bitmap.createScaledBitmap(realImage, width, height, filter);

    return newBitmap;
}

private byte[] convertBitmapToByteArray(Bitmap bmp, int quality) {
    if(quality>100)
        quality = 100;
    if(quality<0)
        quality = 0;

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, quality, stream);
    byte[] byteArray = stream.toByteArray();

    return byteArray;
}

@Override
public byte[] getCapturedPictureAsByteArray(float imageSize, boolean smoothFilter, int quality) {
    Bitmap bitmap = getBitmapFromPath(pictureImagePath);
    Bitmap scaledDownBitmap = scaleDownBitmap(bitmap, imageSize, smoothFilter);
    selectedByteArray = convertBitmapToByteArray(scaledDownBitmap, quality);

    return selectedByteArray;
}

现在是核心游戏端代码的粗略版本:

if(gameMode==GameMode.setTextureFromCapturedPicture) {
        float imageSize = 100; boolean smoothFilter = true; int quality = 10;
        texture = byteArrayToTexture(rootApp.galleryOpener.getCapturedPictureAsByteArray(imageSize, smoothFilter, quality));
        gameMode = GameMode.play;
    }

用于从 byte[] 转换为纹理。

private Texture byteArrayToTexture(byte[] bytes) {
    try {
        Pixmap pmap =new Pixmap(bytes, 0, bytes.length);
        Texture tex =new Texture(pmap);
        return tex;
    } catch(Exception e) {
        e.printStackTrace();
    }

    return null;
}

错误是我拍了一张照片,它带我回到 libgdx 的前一个屏幕(在我的例子中是菜单屏幕)。当我搜索手机的图库时,我找到了该图片并且可以毫无问题地查看它。此外,当我再次运行我的游戏并选择最后选择的图片时,它可以工作:s

最可悲的是错误不能重复产生。它只是崩溃。但是,我遇到的最常见错误是

com.*.*.game/Zygote: v2
com.*.*.game E/Zygote: accessInfo : 0

com.*.*.game waiting for pause synchronization took too long; assuming deadlock and killing

【问题讨论】:

    标签: java android libgdx crash deadlock


    【解决方案1】:

    我的做法是这样的;告诉意图您要将来自相机的图像存储在哪里,否则不会存储任何内容:

    File file = new File(Environment.getExternalStorageDirectory() + IMAGE_FOLDER + File.separator + "temp_image.jpg");
                                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                                takePictureIntent.putExtra(PhotoStatics.OUTPUT_FORMAT, Bitmap.CompressFormat.JPEG.toString());
                                startActivityForResult(takePictureIntent, PhotoStatics.REQUEST_IMAGE_CAPTURE);
    

    然后我们监听照片何时完成,并从我们告诉相机存储图像的位置抓取它...

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        //System.out.println("onActivityResult = " + requestCode + " " + resultCode + " " + intent.getAction());
    
        // Photo incoming
        if (requestCode == PhotoStatics.REQUEST_IMAGE_CAPTURE) {
            if (resultCode == RESULT_OK) { // check if we have something to work with
    
                File file = new File(Environment.getExternalStorageDirectory() + IMAGE_FOLDER + File.separator + "temp_image.jpg");
                Uri image_uri = Uri.fromFile(file); // get where the temp is stored
                Bitmap imageBitmap = BitmapFactory.decodeFile(image_uri.getPath());
            }
        }
    }
    

    这对你有意义吗?

    // Static Globals
    public static final String TEMP_IMAGE = "temp_image";
    public static final String OUTPUT_FORMAT = "outputFormat";
    public static final String IMAGE_FOLDER = "/these_pictures"; // don't forget the / at the beginning.
    public static final int REQUEST_IMAGE_CAPTURE = 12; // just internal use.
    public static final String IMAGE_TYPE = ".jpg";
    

    【讨论】:

    • 感谢您的回复!我会测试它并回复你!
    • 什么是 PhotoStatics.OUTPUT_FORMAT?
    • 添加了我使用的静态方法。
    • 再次感谢您的清理。我测试了它,但它仍然无法正常工作:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多