I need to create .jpeg/.png file on my Android application programmatically. I have simple image (black background), and it need to write some text on it programmatically. How can I do it? Is it possible?
It's definately possible.
To write text on an image you have to load the image in to a Bitmap object. Then draw on that bitmap with the Canvas and Paint functions. When you're done drawing you simply output the Bitmap to a file.
If you're just using a black background, it's probably better for you to simply create a blank bitmap on a canvas, fill it black, draw text and then dump to a Bitmap.
I used this tutorial to learn the basics of the canvas and paint.
This is the code that you'll be looking for to turn the canvas in to an image file:
OutputStream os = null;
try {
File file = new File(dir, "image" + System.currentTimeMillis() + ".png");
os = new FileOutputStream(file);
finalBMP.compress(CompressFormat.PNG, 100, os);
finalBMP.recycle(); // this is very important. make sure you always recycle your bitmap when you're done with it.
screenGrabFilePath = file.getPath();
} catch(IOException e) {
finalBMP.recycle(); // this is very important. make sure you always recycle your bitmap when you're done with it.
Log.e("combineImages", "problem combining images", e);
}
Yes, see here
Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
You can also use awt's Graphics2D with this compatibility project
Using Graphics2d you can create a PNG image as well:
public class Imagetest {
public static void main(String[] args) throws IOException {
File path = new File("image/base/path");
BufferedImage img = new BufferedImage(100, 100,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.YELLOW);
g2d.drawLine(0, 0, 50, 50);
g2d.setColor(Color.BLACK);
g2d.drawLine(50, 50, 0, 100);
g2d.setColor(Color.RED);
g2d.drawLine(50, 50, 100, 0);
g2d.setColor(Color.GREEN);
g2d.drawLine(50, 50, 100, 100);
ImageIO.write(img, "PNG", new File(path, "1.png"));
}
}
Related
I am working with Canvas in Android Studio, have .png image on canvas and want to save it to sd card. Is it possible?
if yes then how?
thanks and regards.
This code may help you (Saving canvas to bitmap on Android)
Bitmap toDisk = null;
try {
// TODO: Get the size of the canvas, replace the 640, 480
toDisk = Bitmap.createBitmap(640,480,Bitmap.Config.ARGB_8888);
canvas.setBitmap(toDisk);
toDisk.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File("arun.jpg")));
} catch (Exception ex) {
}
You should have created Canvas with new Canvas(myBitmap);. So when you draw on the Canvas, it draws to your bitmap.
String fileName = Environment.getExternalStorageDirectory() + "/test.png";
OutputStream stream = new FileOutputStream(fileName);
/* Write bitmap to file using JPEG or PNG and 80% quality hint for JPEG. */
myBitmap.compress(CompressFormat.PNG, 80, stream);
stream.close();
I'm trying to fuond an image editor library that allow me to put a sticker on an image. I've found two libraries, one is Aviary , but I can't put my own stickers in it, then I've tried Android-image-edit but is very simple and it's not a library, it's an application.
Anyone knows some good libraries that allow me to do what I'm trying to do?
Thanks in advance.
I don't know a library, but if I understand you right, you want to add one Drawable onto an image?
You can do this yourself: (untested!)
public void putSticker(File file, Bitmap overlay) {
//Load bitmap from file:
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
bitmap = bitmap.copy(Bitmap.Config.RGB_565, true);
//Draw overlay:
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(overlay, 0, 0, paint);
//Save to file:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 40, bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
fos.write(bitmapdata);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Maybe there is a better way for loading and saving. But drawing is the interesting part for your question, anyway.
See http://developer.android.com/reference/android/graphics/Canvas.html for more drawBitmap() possibilities. (Offsets, Scaling, ...)
I don't know, if anyone's still looking for this, but this library can you in every possible way, to add a sticker.
https://github.com/wuapnjie/StickerView
I am programmatically drawing to a canvas using data entered by the user. Once all of the data is entered, the user can flip through the images and they will be drawn to the canvas. The user has the option to save all of the images(could be several hundred). I use a runnable that runs on the UI thread that will draw and save each image(since you can't draw to a canvas from an AsyncTask). This works, but the problem I am having is if while the saving is going on, the user turns off the screen or minimizes the app. This causes the jpegs to just be black. I would like the saving to be something that could run in the background and still work.
Code used to draw to canvas and save image:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap bitmap;
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas.setBitmap(bitmap);
// draw everything here
OutputStream stream = new FileOutputStream(imageName + ".jpg");
bitmap.compress(CompressFormat.JPEG, 100, stream);
stream.close();
}
So, is there a way for images to be drawn and saved to a file in the background while the canvas is not visible? Any help would be appreciated!
I think you can use this:
signLayout.setDrawingCacheEnabled(true); //signLayout is layout that contains image you want to save
// Save image from layout
String path = "sdcard0/test/test.jpg"; //file path you want to save
gestureSign.save(signLayout, path);
SAVE METHOD
//Save to path
public void save(View v, String SavePath)
{
if(mBitmap == null)
{
mBitmap = Bitmap.createBitmap (layoutSign.getWidth(), layoutSign.getHeight(), Bitmap.Config.RGB_565);;
}
Canvas canvas = new Canvas(mBitmap);
try
{
FileOutputStream mFileOutStream = new FileOutputStream(SavePath);
v.draw(canvas); //Lay toan bo layout
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, mFileOutStream);
mFileOutStream.flush();
mFileOutStream.close();
}
catch(Exception e)
{
Log.v("log_tag", e.toString());
}
}
On android I am drawing into a android.graphics.Picture then save the Picture to a file. Later I reload the picture into memory and draw it to the canvas. I noticed that Bitmaps were never drawing. And after much debugging I managed to narrow down the problem to Picture.writeToStream and Picture.createFromStream. It seems that Bitmaps drawn into the picture don't get reloaded properly. Below is sample code I wrote to show the problem. In this sample my canvas is not hardware accelerated.
So my questions are as follows:
Am I doing something wrong?
Is this an Android bug? I filed the bug report https://code.google.com/p/android/issues/detail?id=54896 because I think this is.
Any known workaround?
#Override
protected void onDraw(Canvas canvas)
{
try
{
Picture picture = new Picture();
// Create a bitmap
Bitmap bitmap = Bitmap.createBitmap( 100, 100, Config.ARGB_8888);
Canvas bitmapCanvas = new Canvas(bitmap);
bitmapCanvas.drawARGB(255, 0, 255, 0);
// Draw the bitmap to the picture's canvas.
Canvas pictureCanvas = picture.beginRecording(canvas.getWidth(), canvas.getHeight());
RectF dstRect = new RectF(0, 0, 200, 200);
pictureCanvas.drawBitmap(bitmap, null, dstRect, null);
picture.endRecording();
// Save the Picture to a file.
File file = File.createTempFile("cache", ".pic");
FileOutputStream os = new FileOutputStream(file);
picture.writeToStream(os);
os.close();
// Read the picture back in
FileInputStream in = new FileInputStream(file);
Picture cachedPicture = Picture.createFromStream(in);
// Draw the cached picture to the view's canvas. This won't draw the bitmap!
canvas.drawPicture(cachedPicture);
// Uncomment the following line to see that Drawing the Picture without reloading
// it from disk works fine.
//canvas.drawPicture(picture);
}
catch (Exception e)
{
}
}
I did find an answer to this question after looking at the native android code that backs the Bitmap. Android only can only save certain types of bitmaps to the picture. This is because the SkBitmap class only supports certain types of inputs that result in a bitmap that can be saved to a Picture. So in this can I can workaround the problem by providing those magical inputs. Use a bitmap that is saved to disk and call BitmapFactory.decodeFileDescriptor to create it.
private Bitmap createReusableBitmap(Bitmap inBitmap)
{
Bitmap reuseableBitmap = null;
if (inBitmap== null)
return null;
try
{
// The caller is responsible for deleting the file.
File tmpBitmapFile = File.createTempFile("bitmap", ".png");
setBitmapPath(tmpBitmapFile.getAbsolutePath());
FileOutputStream out = new FileOutputStream(tmpBitmapFile);
boolean compressed = inBitmap.compress(CompressFormat.PNG, 100, out);
out.close();
if (compressed)
{
// Have to create a purgeable bitmap b/c that is the only kind that works right when drawing into a
// Picture. After digging through the android source I found decodeFileDescriptor will create the one we need.
// See https://github.com/android/platform_frameworks_base/blob/master/core/jni/android/graphics/BitmapFactory.cpp
// In short we have to give the options inPurgeable=true inInputShareable=true and call decodeFileDescriptor
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inInputShareable = true;
options.inPurgeable = true;
options.inSampleSize = 1;
options.inScaled = false;
options.inMutable = false;
options.inTempStorage = DraftRenderer.tempStorage;
FileInputStream inStream = new FileInputStream(tmpBitmapFile);
FileDescriptor fd = inStream.getFD();
reuseableBitmap = BitmapFactory.decodeFileDescriptor(fd, null, options);
inStream.close();
}
} catch (Exception e) {
}
return reuseableBitmap;
}
Note: a picture created from an input stream cannot be replayed on a hardware accelerated canvas.
Picture.createFromStream(InputStream stream)
you can use canvas.isHardwareAccelerated() to detect hardware accelerated or not.
I am using this API demo of the Developer site, THIS DEMO.
But i am wonder that how to save that image in to My Andrtoid Device.
Is please anyone give the Code to save that drawn image to the Android Device.
Thanks.
try this code
View content = your_view;
content.setDrawingCacheEnabled(true);
content.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
Bitmap bitmap = content.getDrawingCache();
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
File file = new File(path+"/image.png");
FileOutputStream ostream;
try {
file.createNewFile();
ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 100, ostream);
ostream.flush();
ostream.close();
Toast.makeText(getApplicationContext(), "image saved", 5000).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "error", 5000).show();
}
drawView.setDrawingCacheEnabled(true);
Bitmap bm = null;
drawView.destroyDrawingCache();
bm=drawView.getDrawingCache();
Then write the bitmap to file using bitmap factory.
One option is create another Canvas (as shown below) and repeat all your drawing on this new canvas.
Once done, call drawBitmap.
Bitmap bitmap = new Bitmap(// Set the params you like //);
Canvas canvas = new Canvas(bitmap);
// Do all your drawings here
canvas.drawBitmap(// The first picture //);
The best would be if there was a way to copy an existing canvas and then you wont need to re-draw everything but I couldn't find one.
I have implemented the below approach & worked for me.
Get your CustomView by using its id from xml file but not by instantiating the Customview.
View v = findViewById(R.id.custom_view);
//don't get customview by this way, View v = new CustomView(this);
int canvasWidth = v.getWidth();
int canvasHeight = v.getHeight();
Bitmap bitmap = Bitmap.createBitmap(canvasWidth, canvasHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
v.draw(canvas);
ImageView imageView = findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);
All code should be inside saveButton click listener.