从 getArguments() 方法检索图像路径后出现 Enoent 错误
Enoent error after retrieving the imagepath from getArguments() method
我有以下错误:
java.io.FileNotFoundException: mounted/snapit!/Image-4774.jpg: open failed: ENOENT (No such file or directory)
基本上一开始我有一个图库,用户可以在其中单击图片。图像应在 Gl SurfaceView 内的另一个片段中打开。然后用户有一些按钮,可以选择一些过滤器来编辑图像。问题是图像根本没有出现在 SurfaceView 上。
这里我获取到所选图片的路径:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
inflate = inflater.inflate(R.layout.fragment_edit, container, false);
Bundle bundle = getArguments();
imagePath = bundle.getString("Image");
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(imagePath, bmOptions);
/**
* Initialise the renderer and tell it to only render when
* Explicit requested with the RENDERMODE_WHEN_DIRTY option
*/
mEffectView = (GLSurfaceView) inflate.findViewById(R.id.effectsview);
mEffectView.setEGLContextClientVersion(2);
mEffectView.setRenderer(this);
mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mCurrentEffect = R.id.none;
我已经检查了 getArguments 和 getString returns 路径,确实如此,所以我认为没有问题。
然后我有以下代码:
private void loadTextures() {
// Generate textures
GLES20.glGenTextures(2, mTextures, 0);
// Load input bitmap
BitmapFactory.Options btmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, btmOptions);
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
mTexRenderer.updateTextureSize(mImageWidth, mImageHeight);
// Upload to texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Set texture parameters
GLToolbox.initTexParams();
}
private void initEffect() {
EffectFactory effectFactory = mEffectContext.getFactory();
if (mEffect != null) {
mEffect.release();
}
/**
* Initialize the correct effect based on the selected menu/action item
*/
switch (mCurrentEffect) {
case R.id.none:
break;
case R.id.fisheye:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_FISHEYE);
mEffect.setParameter("scale", .5f);
break;
case R.id.grain:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_GRAIN);
mEffect.setParameter("strength", 1.0f);
break;
case R.id.negative:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_NEGATIVE);
break;
case R.id.duotone:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_DUOTONE);
mEffect.setParameter("first_color", Color.YELLOW);
mEffect.setParameter("second_color", Color.DKGRAY);
break;
case R.id.documentary:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_DOCUMENTARY);
break;
default:
break;
}
}
private void applyEffect() {
mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]);
}
private void renderResult() {
if (mCurrentEffect != R.id.none) {
// if no effect is chosen, just render the original bitmap
mTexRenderer.renderTexture(mTextures[1]);
} else {
saveFrame = true;
// render the result of applyEffect()
mTexRenderer.renderTexture(mTextures[0]);
}
}
@Override
public void onDrawFrame(GL10 gl) {
if (!mInitialized) {
//Only need to do this once
mEffectContext = EffectContext.createWithCurrentGlContext();
mTexRenderer.init();
loadTextures();
mInitialized = true;
}
if (mCurrentEffect != R.id.none) {
//if an effect is chosen initialize it and apply it to the texture
initEffect();
applyEffect();
}
renderResult();
if (saveFrame) {
saveBitmap(takeScreenshot(gl));
}
}
private boolean saveBitmap(Bitmap bitmap) {
boolean status = false;
String root = Environment.getExternalStorageState().toString();
File myDir = new File(root + "/snapit!");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
Log.i("TAG", "Image SAVED==========" + file.getAbsolutePath());
status = true;
} catch (Exception e) {
e.printStackTrace();
}
return status;
}
public Bitmap takeScreenshot(GL10 mGL) {
final int mWidth = mEffectView.getWidth();
final int mHeight = mEffectView.getHeight();
IntBuffer ib = IntBuffer.allocate(mWidth * mHeight);
IntBuffer ibt = IntBuffer.allocate(mWidth * mHeight);
mGL.glReadPixels(0, 0, mWidth, mHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
// Convert upside down mirror-reversed button to right-side up normal
// button.
for (int i = 0; i < mHeight; i++) {
for (int j = 0; j < mWidth; j++) {
ibt.put((mHeight - i - 1) * mWidth + j, ib.get(i * mWidth + j));
}
}
Bitmap mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mBitmap.copyPixelsFromBuffer(ibt);
return mBitmap;
}
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (mTexRenderer != null) {
mTexRenderer.updateViewSize(width, height);
}
}
public void setCurrentEffect(int effect) {
mCurrentEffect = effect;
}
@Override
public void onClick(View v) {
setCurrentEffect(v.getId());
mEffectView.requestRender();
}
起初我以为图片太大了,所以我尝试用小的,但没有运气..
我的预感是问题是因为你的文件夹名称末尾有一个感叹号;尝试没有! (mounted/snapit/Image-4774.jpg
)
有关说明,请参阅 this post。
我做了一些重构,更改了一些代码,现在它可以工作了。没有找出为什么它在上面的代码中不起作用。
我有以下错误:
java.io.FileNotFoundException: mounted/snapit!/Image-4774.jpg: open failed: ENOENT (No such file or directory)
基本上一开始我有一个图库,用户可以在其中单击图片。图像应在 Gl SurfaceView 内的另一个片段中打开。然后用户有一些按钮,可以选择一些过滤器来编辑图像。问题是图像根本没有出现在 SurfaceView 上。
这里我获取到所选图片的路径:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
inflate = inflater.inflate(R.layout.fragment_edit, container, false);
Bundle bundle = getArguments();
imagePath = bundle.getString("Image");
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(imagePath, bmOptions);
/**
* Initialise the renderer and tell it to only render when
* Explicit requested with the RENDERMODE_WHEN_DIRTY option
*/
mEffectView = (GLSurfaceView) inflate.findViewById(R.id.effectsview);
mEffectView.setEGLContextClientVersion(2);
mEffectView.setRenderer(this);
mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mCurrentEffect = R.id.none;
我已经检查了 getArguments 和 getString returns 路径,确实如此,所以我认为没有问题。
然后我有以下代码:
private void loadTextures() {
// Generate textures
GLES20.glGenTextures(2, mTextures, 0);
// Load input bitmap
BitmapFactory.Options btmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, btmOptions);
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
mTexRenderer.updateTextureSize(mImageWidth, mImageHeight);
// Upload to texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Set texture parameters
GLToolbox.initTexParams();
}
private void initEffect() {
EffectFactory effectFactory = mEffectContext.getFactory();
if (mEffect != null) {
mEffect.release();
}
/**
* Initialize the correct effect based on the selected menu/action item
*/
switch (mCurrentEffect) {
case R.id.none:
break;
case R.id.fisheye:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_FISHEYE);
mEffect.setParameter("scale", .5f);
break;
case R.id.grain:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_GRAIN);
mEffect.setParameter("strength", 1.0f);
break;
case R.id.negative:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_NEGATIVE);
break;
case R.id.duotone:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_DUOTONE);
mEffect.setParameter("first_color", Color.YELLOW);
mEffect.setParameter("second_color", Color.DKGRAY);
break;
case R.id.documentary:
mEffect = effectFactory.createEffect(
EffectFactory.EFFECT_DOCUMENTARY);
break;
default:
break;
}
}
private void applyEffect() {
mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]);
}
private void renderResult() {
if (mCurrentEffect != R.id.none) {
// if no effect is chosen, just render the original bitmap
mTexRenderer.renderTexture(mTextures[1]);
} else {
saveFrame = true;
// render the result of applyEffect()
mTexRenderer.renderTexture(mTextures[0]);
}
}
@Override
public void onDrawFrame(GL10 gl) {
if (!mInitialized) {
//Only need to do this once
mEffectContext = EffectContext.createWithCurrentGlContext();
mTexRenderer.init();
loadTextures();
mInitialized = true;
}
if (mCurrentEffect != R.id.none) {
//if an effect is chosen initialize it and apply it to the texture
initEffect();
applyEffect();
}
renderResult();
if (saveFrame) {
saveBitmap(takeScreenshot(gl));
}
}
private boolean saveBitmap(Bitmap bitmap) {
boolean status = false;
String root = Environment.getExternalStorageState().toString();
File myDir = new File(root + "/snapit!");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
Log.i("TAG", "Image SAVED==========" + file.getAbsolutePath());
status = true;
} catch (Exception e) {
e.printStackTrace();
}
return status;
}
public Bitmap takeScreenshot(GL10 mGL) {
final int mWidth = mEffectView.getWidth();
final int mHeight = mEffectView.getHeight();
IntBuffer ib = IntBuffer.allocate(mWidth * mHeight);
IntBuffer ibt = IntBuffer.allocate(mWidth * mHeight);
mGL.glReadPixels(0, 0, mWidth, mHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
// Convert upside down mirror-reversed button to right-side up normal
// button.
for (int i = 0; i < mHeight; i++) {
for (int j = 0; j < mWidth; j++) {
ibt.put((mHeight - i - 1) * mWidth + j, ib.get(i * mWidth + j));
}
}
Bitmap mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mBitmap.copyPixelsFromBuffer(ibt);
return mBitmap;
}
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (mTexRenderer != null) {
mTexRenderer.updateViewSize(width, height);
}
}
public void setCurrentEffect(int effect) {
mCurrentEffect = effect;
}
@Override
public void onClick(View v) {
setCurrentEffect(v.getId());
mEffectView.requestRender();
}
起初我以为图片太大了,所以我尝试用小的,但没有运气..
我的预感是问题是因为你的文件夹名称末尾有一个感叹号;尝试没有! (mounted/snapit/Image-4774.jpg
)
有关说明,请参阅 this post。
我做了一些重构,更改了一些代码,现在它可以工作了。没有找出为什么它在上面的代码中不起作用。