Capture photo and apply effects (scale, rotate, grey, draw with finger) - android

I am trying to capture a photo and after that, allow to the user to add some effects, draw, drag other assets to the image, add text, etc. Like snapchat camera.
I have followed the Camera 2 API sample. The major part of the code is at
Camera2BasicFragment.java
I have achieved the capture and preview image, but the example set the image in a TextureView, but I do not have idea how to continue to manipulate the image.
I dont know if I should use a TextureView or a Canvas or a SurfaceView.
An example of the final image result that I want:
Thanks in advance.

Capture your photo , save your image. Then in an ImageView you can apply all kind of effects that you want using Bitmap and ColorMatrix.
Here I give a small sample to make an image grayscale
public void toGrayscale() {
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
imageView.setColorFilter(filter);
}
After applying the effects just save drawable to image file like this:
public void saveDrawable(ImageView imageView) throws FileNotFoundException {
Bitmap bitmap = getBitmapFromImageView(imageView);
OutputStream fOut = null;
try {
fOut = new FileOutputStream(absolutePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 95, fOut);
} finally {
if (fOut != null) {
try {
fOut.close();
} catch (IOException e) {
//report error
}
}
}
}
#NonNull
private Bitmap getBitmapFromImageView(ImageView imageView) {
Drawable drawable = imageView.getDrawable();
Rect bounds = drawable.getBounds();
Bitmap bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.draw(canvas);
return bitmap;
}
There is a good library that will help you https://github.com/chrisbanes/PhotoView
To draw with a finger this question how to draw line on imageview along with finger in android should help you
Hope its helps!!

Related

Write bitmap messed up with horizontal lines

I am attempting to finger draw on a transparent bitmap. The canvas Im using draws the image just fine, but when I save the image, the image shows like below, with all the horizontal transparent lines.
I draw using the following code.
private void doDraw(Canvas canvas) {
mOffScreenCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
for(int index = 0; index < mAnnotations.size(); index++) {
InkAnnotation annotation = mAnnotations.get(index);
annotation.draw(mOffScreenCanvas, ActivityPageToolBar.mCurrentTool.paint());
}
if(canvas != null && mSurface != null) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawBitmap(mSurface, 0, 0, mPaint);
}
}
The file is saved using
Bitmap saveBitmap = Bitmap.createBitmap(map);
Canvas c = new Canvas(saveBitmap);
c.drawColor(0xFFFFFFFF);
c.drawBitmap(map,0,0,null);
i use standard file saving to save it
try {
FileOutputStream out = handle.outputStream();
if(handle.fileName().contains(".png")) {
((Bitmap) handle.data()).compress(CompressFormat.PNG, quality, out);
} else if(handle.fileName().contains(".jpg") || handle.fileName().contains(".jpeg")) {
((Bitmap) handle.data()).compress(CompressFormat.JPEG, quality, out);
} else {
((Bitmap) handle.data()).compress(CompressFormat.WEBP, quality, out);
}
out.flush();
out.close();
} catch(Exception e) {
e.printStackTrace();
}
Any way to fix this issue? At the same time I am embedding the bitmap into a pdf and the colors are darker than they should be.
This is what the image looks like on the screen before I save it. The background is irrelevant, i can draw to the screen just fine, but when it save it to a png it looks messed up.
I solved this by taking the points I created on the surfaceview and creating a new bitmap from those points. There must be something the surface it doing to its bitmap to cause this.

Android draw area from Bitmap or Imageview with canvas

i'm trying to draw a Bitmap but only with a selected area from the original Bitmap or Imageview. The requirement is that the final picture must show only 1/3 from the top of the original Bitmap. I attach a draft. I suppose that i should use canvas, but i do not know exactly how it works.
Thanks in advance!!
Bitmap getTheReducedBitmap(Bitmap fullLengthBitnap)
{
Bitmap backDrop=Bitmap.createBitmap(fullLengthBitnap.getWidth(), fullLengthBitnap.getHeight()/3, Bitmap.Config.RGB_565);
Canvas can = new Canvas(backDrop);
can.drawBitmap(fullLengthBitnap, 0, 0, null);
return backDrop;
}
This is the documentation for the method you should use.
private void draw(Canvas c, Bitmap bmp){
Rect r=new Rect(0,0,bmp.width,bmp.height/3);
Rect drawR=new Rect(0,0,c.width,c.height/3);
c.drawBitmap(bmp,r,drawR,null);
}
or as a one liner:
c.drawBitmap(bmp,new Rect(0,0,bmp.width,bmp.height/3),new Rect(0,0,c.width,c.height/3),null);
It allows you to specify where on the canvas you want to draw it too, and where you want the segment to be from.
#Eu.Dr. 's answer would not work if you wanted to draw anything else on the canvas below it.
val newBitmap=Bimtap
.createBitmap(your_view.width,your_view.height,Bitmap.Config.ALPHA_8)
//note: for tablet mode your_view.width,height will increase drastically so
//you might want
//to fix the size of drawing area for optimization
//ALPHA_8 each pixel requires 1 byte of memory.
//RGB_565 Each pixel is stored on 2 bytes
//ARGB_8888 Each pixel is stored on 4 bytes
//after this you can further apply the compress like
[Refer more from google][1]
val stream = ByteArrayOutputStream();
newBitmap.compress(Bitmap.CompressFormat.PNG, 80, stream);
val byteArray = stream.toByteArray(); // convert drawing photo to byte array
// save it in your internal storage.
val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES
+"attendance_sheet.png");
try{
val fo = FileOutputStream(storageDir);
fo.write(byteArray);
fo.flush();
fo.close();
}catch(Exception ex){
}

Save canvas to jpeg while canvas is not visible

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());
}
}

Saving Bitmap drawn on Canvas

In my application I extended the ImageView and overriden its onDraw() method. I am using a color filter to manipulate the bitmap for adding some effects like invert, grayscale etcc. After drawing the bitmap I am trying to save it but I am only able to save the original bitmap with no added effects. Here is the code for onDraw() and save method:
protected void onDraw(Canvas canvas)
{
Paint paint = mPaint;
//cmf is the color matrix filter
paint.setColorFilter(cmf);
if(mBitmap != null)
{
canvas.drawBitmap(mBitmap, offsetW, offsetH, paint);
}
}
code for saving the bitmap:
try
{
FileOutputStream fout = new FileOutputStream(path);
mBitmap.compress(CompressFormat.JPEG, 100, fout);
} catch (FileNotFoundException e)
{
e.printStackTrace();
}
Am I doing something wrong? Any help will be appretiated.
You are painting on the canvas that is displayed, original bitmap is not changed. You should create a new bitmap and paint on it. When color matrix filter changes do this:
Bitmap tmp = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig())
Canvas canvas = new Canvas(tmp)
cnvas.drawBitmap(tmp, 0, 0, paint);
Then, you can use this tmp bitmap to draw it and save it.
Instead of using customized ImageView use a normal one and set its image to this new bitmap:
imageView.setImageBitmap(tmp)

Android combine pictures

Hy, I tried to search this but not very much luck
the most similar is this one
http://ketankantilal.blogspot.com/2011/03/how-to-combine-images-and-store-to.html
Anyhow, I'm developing for android.
The question is I have images in png format (or jpg as bmp is quite large for my app).
How can I combine three images from top to bottom.
I do not need to save them on sd just to display them.
Thanks, and sorry if a similar question with answer exists.
You could use a Canvas and then draw each Bitmap (assuming each image is loaded into a Bitmap object) using appropriate top and left offsets.
You would increase the top offset of the next bitmap by the total size of the previously drawn Bitmaps.
Check out http://developer.android.com/reference/android/graphics/Canvas.html
example:
public void stackImages(Context ctx)
{
// base image, if new images have transparency or don't fill all pixels
// whatever is drawn here will show.
Bitmap result = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
// b1 will be on top
Bitmap b1 = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888);
// b2 will be below b1
Bitmap b2 = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);
c.drawBitmap(b1, 0f, 0f, null);
// notice the top offset
c.drawBitmap(b2, 0f, 200f, null);
// result can now be used in any ImageView
ImageView iv = new ImageView(ctx);
iv.setImageBitmap(result);
// or save to file as png
// note: this may not be the best way to accomplish the save
try {
FileOutputStream out = new FileOutputStream(new File("some/file/name.png"));
result.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
}

Categories

Resources