I'm getting an image from a URL, I want to compress it and save it in the external memory device. I get this error
java.lang.IllegalStateException:
Can't compress a recycled bitmap
at android.graphics.Bitmap.checkRecycled(Bitmap.java:400)
at android.graphics.Bitmap.compress(Bitmap.java:1307)
at this line
mIcon11.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
String foto = UT_drive_dropbox.AM.getfoto();
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(foto).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
final Bitmap output = Bitmap.createBitmap(mIcon11.getWidth(),
mIcon11.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, mIcon11.getWidth(), mIcon11.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(mIcon11, rect, rect, paint);
mIcon11.recycle();
String fileName = "avatar.jpg";
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
mIcon11.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
File sd = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name) + File.separator + fileName);
FileOutputStream fileOutputStream = null;
try {
sd.createNewFile();
fileOutputStream = new FileOutputStream(sd);
fileOutputStream.write(bytes.toByteArray());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The error message is "Can't compress a recycled bitmap". If you look three lines before your mIcon11.compress(Bitmap.CompressFormat.JPEG, 40, bytes); line, you will see:
mIcon11.recycle();
So, either get rid of recycle() or move it to after you have done everything that you intend to do with the Bitmap pointed to by mIcon11.
I'm an android beginner with little knowledge of coding. I've implemented a save button in my viewfippler gallery but I'm getting two errors on this line " Bitmap bitmap = getBitmapFromImageView(ImageView imageView);" in the saveimage() method. The compiler is saying there's a ")" expected and there's an illegal start of expression on the line specified above. The relevant code is below.
ViewFlipper.java
public class ViewFlipperActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.btnSave).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
saveimage();
}
});
........
}
public Bitmap getBitmapFromImageView(ImageView imageView) {
int viewWidth = imageView.getWidth();
int viewHeight = imageView.getHeight();
Bitmap bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
imageView.layout(0, 0, viewWidth, viewHeight);
imageView.draw(canvas);
return bitmap;
}
public static void saveimage(){
Bitmap bitmap = getBitmapFromImageView(ImageView imageView);
File f =new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/HD GOSPEL LOCKSCREENS");
if(!f.exists())
{
f.mkdirs();
}
f = new File(f.getAbsolutePath(),
String.valueOf(System.currentTimeMillis()) +"hdgospelLockScreen.jpg");
if(!f.exists())
{
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(f));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
.......
}
Your syntax is incorrect. Change this line: Bitmap bitmap = getBitmapFromImageView(ImageView imageView); to Bitmap bitmap = getBitmapFromImageView(imageView); where imageView is an ImageView object.
EDIT: Also, your static function saveImage should take in the ImageView object:
public static void saveImage(ImageView imageView) {
I need to convert string in the edittext to bitmap, but i am not getting the string but instead i am getting this (see the image)
my code is as follows
Canvas c=new Canvas();
MainActivity.editText.setCursorVisible(false);
MainActivity.editText.buildDrawingCache();
Bitmap bmp = Bitmap.createBitmap(MainActivity.editText.getDrawingCache());
System.out.println("string is "+MainActivity.editText.getText().toString());
File f =new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Photo Text");
if(!f.exists())
{
f.mkdirs();
}
f = new File(f.getAbsolutePath(),
String.valueOf(System.currentTimeMillis()) +"phototext.jpg");
if(!f.exists())
{
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
bmp.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(f));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c.drawBitmap(bmp,0,0, mPaint);
Please suggest me. I need the string from the edittext as a bitmap.
Why not get the text of the ExitText and then draw it on Canvas with drawText()?
String text = editText.getText().toString();
canvas.drawText(text, 0, 0, paint);
and set the canvas height and width depending of text height and length.
i am developing image editor and im using custom class to draw bitmap, here is my code..
private void settingBitmapToDraw() {
// TODO Auto-generated method stub
resultBitmap=Bitmap.createScaledBitmap(resultBitmap, WIDTH, HEIGHT, true);
Matrix matrix=new Matrix();
matrix.setRotate(TO_DEGREE);
tempBitmap=Bitmap.createBitmap(resultBitmap, 0, 0, WIDTH, HEIGHT,
matrix, true);
bitmap=Bitmap.createBitmap(WIDTH, HEIGHT, tempBitmap.getConfig());
canvas=new Canvas(bitmap);
invalidate();
}
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawBitmap(tempBitmap, xAxis, yAxis, paint);
if(overlayBitmap!=null)
{
canvas.drawBitmap(overlayBitmap, xAxis+50, yAxis+50, paint);
}
}
public void overlayImage() {
// TODO Auto-generated method stub
ImageProcessing.SAVE_STATUS=false;
overlayBitmap=BitmapFactory.decodeResource(getResources(),
R.drawable.add_image);
invalidate();
}
The bitmap is drawn on canvas but while saving it saves as a black image.
this is my save bitmap code...
try {
FileOutputStream fos=new FileOutputStream(file);
updatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
SAVE_STATUS=true;
saveDialog.dismiss();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
updated bitmap is initialized by 'bitmap'
public Bitmap getUpdatedImage() {
// TODO Auto-generated method stub
//width=2048 height=1232
Bitmap updatedBitmap=Bitmap.createScaledBitmap(bitmap,
orgWidth, orgHeight, true);
return updatedBitmap;
}
//////////////
my ImageProcessing.java class has code...
if(!SAVE_STATUS)
{
updatedBitmap=ip_DrawingClass.getUpdatedImage();
if(updatedBitmap!=null)
{
file=new File(file_root);
saveDialog.show();
}
else
{
Toast.makeText(ImageProcessing.this,
"file can't saved...", Toast.LENGTH_SHORT).show();
}
}
and saveDialog has save button which holds code for saving image written above.
///////////////////////////
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
float xAxis,yAxis;
switch(event.getAction()&MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
MODE="DRAG";
startX=event.getX();
startY=event.getY();
if(ImageProcessing.drawLineStatus)
path.moveTo(startX, startY);
break;
case MotionEvent.ACTION_POINTER_DOWN:
MODE="ZOOM";
oldDist=this.findDistanceXY(event);
break;
case MotionEvent.ACTION_MOVE:
if(MODE=="ZOOM")
{
newDist=findDistanceXY(event);
if(newDist>oldDist)
{
this.applyZooming("plus");
}
else
{
this.applyZooming("minus");
}
oldDist=newDist;
}
else if(MODE=="DRAG")
{
xAxis=event.getX();
yAxis=event.getY();
if(!lock_status)
{
this.translateImage(xAxis,yAxis,startX,startY);
}
else
{
this.translateTextOnBitmap
(xAxis,yAxis,startX,startY);
}
if(ImageProcessing.drawLineStatus)
{
path.lineTo(xAxis, yAxis);
this.drawLinesOnBitmap();
}
else
draw_line=false;
}
break;
case MotionEvent.ACTION_POINTER_UP:
MODE="DRAG";
this.setZoomBoxXY();
break;
case MotionEvent.ACTION_UP:
this.set_XY_Axis();
break;
}
return true;
}
image translate here..
public void translateImage(float x, float y, float startX, float startY) {
// TODO Auto-generated method stub
if((startX>=imageAtX&&startX<=(imageAtX+imageW))&&
(startY>=imageAtY&&startY<=(imageAtY+imageH)))
{
if(imagePortionSelected||crop_status)
{
if((startX>=selectorAtX&&startX<=(selectorAtX+ZOOM))
&&(startY>=selectorAtY&&startY<=(selectorAtY+ZOOM)))
{
left=(int)(x-(startX-selectorAtX));
top=(int)(y-(startY-selectorAtY));
right=left+ZOOM;
bottom=top+ZOOM;
checkForValidityOfPara();
}
rect.set(left, top, right, bottom);
}
else
{
xAxis=x-(startX-imageAtX);
yAxis=y-(startY-imageAtY);
}
}
invalidate();
}
For combining 2 bitmaps use below method
public Bitmap combineImages(Bitmap frame, Bitmap image) {
Bitmap cs = null;
Bitmap rs = null;
rs = Bitmap.createScaledBitmap(frame, image.getWidth(),
image.getHeight(), true);
cs = Bitmap.createBitmap(rs.getWidth(), rs.getHeight(),
Bitmap.Config.RGB_565);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(image, 0, 0, null);
comboImage.drawBitmap(rs, 0, 0, null);
if (rs != null) {
rs.recycle();
rs = null;
}
Runtime.getRuntime().gc();
return cs;
}
And for saving combined Image use below code wherever you want...
Bitmap outBmp = combineImages(bmp1, bmp2);
imageFileFolder = new File(Environment.getExternalStorageDirectory(),
"FOLDER_PHOTOS");
imageFileFolder.mkdir();
FileOutputStream out1 = null;
imageFileName = new File(imageFileFolder, "file_name.jpg");
out1 = new FileOutputStream(imageFileName);
outBmp.compress(Bitmap.CompressFormat.JPEG, 100, out1);
out1.flush();
out1.close();
Use this code. you have to save your drawing layout as the image. hope below code will help you.
Bitmap bm;
DrawingLayout.setDrawingCacheEnabled(true);
bm = DrawingLayout.getDrawingCache();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
//String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/drawn_image";
String path = getFilesDir() .getAbsolutePath();
boolean exists = (new File(path)).exists();
/*if (!exists) {
new File(path).mkdirs();
}*/
OutputStream outStream = null;
File file = new File(path, "drawn_image" + ".PNG");
try {
outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You are not drawing on the updated bitmap. Draw the first bitmap and the overlay bitmap on the updated one before saving it. Change your getUpdatedImage() to this-
protected void getUpdatedImage() {
int width = tempBitmap.getWidth();
int height = tempBitmap.getHeight();
Bitmap updatedBitmap=Bitmap.createScaledBitmap(bitmap,
width, height, true);
Canvas canvas = new Canvas(updatedBitmap);
canvas.drawBitmap(tempBitmap, xAxis, yAxis, paint);
if(overlayBitmap!=null)
{
canvas.drawBitmap(overlayBitmap, xAxis+50, yAxis+50, paint);
}
//now save the updated bitmap
return updatedBitmap;
}
to save bitmap try this...-
public void savebitmap(final Bitmap bitmap)
{
AlertDialog.Builder alert = new AlertDialog.Builder(Work.this);
alert.setMessage("File name :"); //get file name from user
input = new EditText(Work.this);
input.setLayoutParams(new LayoutParams(100,50));
alert.setView(input);
alert.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String _mNameValue = input.getText().toString();
try
{
File fn=new File("/sdcard/"+_mNameValue+".png");
FileOutputStream out=new FileOutputStream(fn);
Toast.makeText(getApplicationContext(), "In Save",Toast.LENGTH_SHORT).show();
bitmap.compress(Bitmap.CompressFormat.PNG, 90,out);
out.flush();
out.close();
Toast.makeText(getApplicationContext(), "File is Saved in "+fn, Toast.LENGTH_SHORT).show();
}
catch(Exception e){
e.printStackTrace();
}
}
});
alert.show();
}
this is working perfectly at my place.
ontouch event-
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(getResources().getColor(R.color.Yellow)) ;
paint.setAlpha(opacity);
_ImageView.setAdjustViewBounds(true);
_ImageView.setImageBitmap(_MutableImage1);
canvas1 = new Canvas(_MutableImage1);
canvas1.drawRect(event.getX()-10,event.getY()-10,event.getX()+10,event.getY()+10, paint);
bitmap1=_MutableImage1.copy(Bitmap.Config.ARGB_4444,false);
I was create image on the canvas using colorfilter
This my code
int color = mPaint.getColor();
f = new LightingColorFilter(color, 1);
mPaint.setColorFilter(f);
myBmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon10);
canvas.drawBitmap(myBmp, 20, 20, mPaint);
canvas.save();
canvas.restore();`
and then,I want to save it to sdcard
OutputStream outStream = null;
File file = new File(extStorageDirectory, "er.PNG");
try {
outStream = new FileOutputStream(file);
myBmp.compress(Bitmap.CompressFormat.PNG, 85, outStream);
outStream.flush();
outStream.close();
Toast.makeText(Draw.this, "Saved", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(Draw.this, e.toString(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(Draw.this, e.toString(), Toast.LENGTH_LONG).show();
}
It's Work But have Problem,My picture on sd is old picture(not filter)
can I fix this problem??,Thank
You need draw into Bitmap. Try below:
int color = mPaint.getColor();
f = new LightingColorFilter(color, 1);
mPaint.setColorFilter(f);
Bitmap outBitmap = Bitmap.Create(myBmp.getWidth(),myBmp.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(outBitmap);
canvas.drawBitmap(myBmp,20,20,mPaint);
And than you can "save it"(outBitmap) to SD card.
If you're open Bitmap with BitmapFactory you'd get immutable bitmap, and can't draw on it.
That's why you need to create temp. Bitmap, connect Canvas for draw, Drawing and can saving.