Thanks for reading, have been trying to get this going for days and have searched as much code as I can. As you will see below I have tried a number of approaches.
I am using a 3rd party device that returns a Bitmap of size 152 x 500. There is a black strip vertically down the left side that is 24 wide. So in actual fact what I am needing is a 128 x 500 which would start 24 in from the left.
Whatever I try I just cannot seem to get rid of that black strip when the image is saved.
Here is the code, sorry it's so much but I thought I would just show it all. Look for
// Scan Button Clicked
and
Log.e("tag", "Wait For Scan Capture");
Much appreciate any help on this.
public class ImageCaptureActivity extends Activity implements OnClickListener {
private LinearLayout ll_root;
private Button btn_scan;
private Button btn_process;
private LinearLayout mLayout;
private Button mButton;
private FingerView mImageView;
private FPCDevKitInterface mFPCDevKit;
public View minutiaView;
public Bitmap tempBitmap;
public Bitmap scanBitmap;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_login_scan);
Log.e("tag", "0");
//ll_root = (LinearLayout)findViewById(R.id.ll_root);
btn_scan = (Button)findViewById(R.id.scan);
btn_process = (Button)findViewById(R.id.proceed_button);
Log.e("tag", "1");
// mFPCDevKit = new SSDDevice ((UsbManager) getSystemService(Context.USB_SERVICE));
// mImageView = new FingerView(this, mFPCDevKit.createCompatibleBitmap());
// mImageView.setLayoutParams(new LinearLayout.LayoutParams(200,200));
//add view here.
// ll_root.addView(mImageView);
// Just keep it commented, because we cannot find the id of ll_root. it is currently null.
Log.i("tag", "2");
Log.e("tag", "5");
/* ---------------------------------------------------------------------------------------------------------------*/
/* Following is the initial Screen Layout Section done as a Setup of the screen and Before the Capture is clicked */
// Manually set up the screen layout
mLayout = new LinearLayout(this);
mLayout.setOrientation(LinearLayout.VERTICAL);
// Manually create the Button
mButton = new Button(this);
mButton.setOnClickListener(this);
mButton.setText("Capture Image");
// Setup the FPC Service to get the finger scan from the device
Log.e("tag", "Setup FPC");
mFPCDevKit = new SSDDevice ((UsbManager) getSystemService(Context.USB_SERVICE));
// Call the FingerView function and then load the bitmap into mImageView
Log.e("tag", "Load into mImageView");
mImageView = new FingerView(this, mFPCDevKit.createCompatibleBitmap());
// Modify the viewing area for the scanned image size
mImageView.setLayoutParams(new LinearLayout.LayoutParams(24+128,500)); // Left area plus image width and crop of right area
// Add the Button and the mImageView to the Layout
Log.e("tag", "Add Views");
mLayout.addView(mButton);
mLayout.addView(mImageView);
// Display the screen
Log.e("tag", "Display Screen");
setContentView(mLayout);
// setContentView(R.layout.my_login_scan);
/* ----------- End Screen Layout Setup ------------------ */
}
public static AlertDialog createCapturePromtDialog(Context context,
DevKitType type) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
if (type == DevKitType.ASD)
builder.setTitle("Place finger on sensor");
else
builder.setTitle("Swipe finger over sensor");
return builder.create();
}
private class FingerView extends View {
public Bitmap mBitmap;
private Matrix mMatrix;
public FingerView(Context context, Bitmap bitmap) {
super(context);
mBitmap = bitmap;
mMatrix = new Matrix();
setBackgroundColor(Color.WHITE); // is the full screen area background colour as well as the template area colour
setDrawingCacheEnabled(true);
Log.e("tag", "FingerView");
}
public Bitmap getBitmap() {
return mBitmap;
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.e("onSizeChanged", "w = " + w + " h = " + h + " oldw = " + oldw
+ " oldh = " + oldh);
// This use to Scale the current bitmap fill the screen.
// The last variable: Matrix.ScaleToFit.FILL for fill two dimensions
// Matrix.ScaleToFit.CENTER scale to center and keep the
// width/height ratio.
//mMatrix.setRectToRect(
// new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight()),
// new RectF(0, 0, w, h), Matrix.ScaleToFit.CENTER);
super.onSizeChanged(w, h, oldw, oldh);
// Lets try to resize to 150 x 500 - Harry July 14 2013
// mMatrix.setRectToRect(new RectF(0, 0, 128, 500),new RectF(-24, 0, 150, 500), Matrix.ScaleToFit.CENTER);
Log.e("tag", "Inside onsizechanged " + 0);
/* Scales image to fit into a new rectangle imageView
Matrix m = imageView.getImageMatrix();
RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight);
RectF viewRect = new RectF(0, 0, imageView.getWidth(), imageView.getHeight());
m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);
imageView.setImageMatrix(m);
*/
}
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas) {
Log.e("onDraw Begin","");
canvas.drawBitmap(mBitmap, mMatrix, null);
super.onDraw(canvas);
}
}
// Scan Button Clicked
public void onClick(View v) {
Log.e("tag", "onClick happened");
// Erase the scan area to White
mImageView.getBitmap().eraseColor(Color.WHITE); // Doesn't seem to make a difference
// Bitmap tempBitmap = Bitmap.createBitmap(128+24+24,500,Bitmap.Config.ARGB_8888);
Log.e("onClick Enter second one= " + 0,
"w = " + 0 + " h =" + 0);
try {
// Wait for the scanner and then load the image into mImageView.mBitmap
mFPCDevKit.clearAbort();
Log.e("tag", "Wait For Scan Capture");
scanBitmap = mFPCDevKit.createCompatibleBitmap();
mFPCDevKit.waitAndCaptureImage(mImageView.getBitmap()); // Image displays in mImageView
//mFPCDevKit.waitAndCaptureImage(scanBitmap); // Tried to put image into a Bitmap
//Create a new image bitmap and attach a brand new canvas to it
// Bitmap minBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas tempCanvas = new Canvas(scanBitmap);
//Draw the image bitmap into the canvas
// tempCanvas.drawBitmap(scanBitmap, 0, 0, null);
//Draw everything else you want into the canvas, in this example a rectangle with rounded edges
// tempCanvas.drawRoundRect(new RectF(x1,y1,x2,y2), 2, 2, scanBitmap);
//Attach the canvas to the ImageView
// mImageView.setBackgroundDrawable(new BitmapDrawable(getResources(), scanBitmap));
// #Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFAAAAAA); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); if(item_id==3){ canvas.drawText(AppModel.contents, 100, 100, mPaint); } else{ canvas.drawPath(mPath, mPaint); } }
// Bitmap mmBitmap = Bitmap.createBitmap(mImageView.mBitmap, 22, 0, mImageView.mBitmap.getWidth()-100, mImageView.mBitmap.getHeight());
// Canvas canvas1 = new Canvas(mmBitmap);
// mImageView.setImageBitmap(tempBitmap);
// Crop the image here.
Log.e("before crop", "w = " + mImageView.getBitmap().getWidth()
+ " h = " + mImageView.getBitmap().getHeight());
// parameters show w = 176 h = 500
// Harry's mods to flow here --------
// Bitmap HarryBitmap = Bitmap.createBitmap(mImageView.getWidth(),mImageView.getHeight(),Bitmap.Config.ARGB_8888);
// Bitmap HarryBitmap = Bitmap.createBitmap(128,500,Bitmap.Config.ARGB_8888);
// Canvas canvas = new Canvas(HarryBitmap);
// mImageView.draw(canvas);
// Bitmap resizedbitmap1 = Bitmap.createBitmap(tempBitmap,24,0,150,500);
// Canvas canvas1 = new Canvas(resizedbitmap1);
// mImageView.draw(canvas1);
/* Try number 2 to approach
Paint paint = new Paint();
paint.setFilterBitmap(true);
int targetWidth = 128;
int targetHeight = 500;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(scanBitmap);
canvas.drawBitmap( scanBitmap, new Rect(24, 0, 176, 500),
new RectF(0, 0, targetWidth, targetHeight), paint);
// Matrix matrix = new Matrix();
// matrix.postScale(1f, 1f);
// Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap, 0, 0, 128, 500, matrix, true);
//
// //convert Bitmap to resource
// //BitmapDrawable bd = new BitmapDrawable(resizedBitmap);
//
// canvas.drawBitmap( resizedBitmap, new Rect(24, 0, 128, 500),
// new Rect(0, 0, 128, 500), paint);
mImageView.draw(canvas);
*/
Log.e("after crop", "w = " + mImageView.getBitmap().getWidth()
+ " h = " + mImageView.getBitmap().getHeight());
// end Harry's mods to flow --------
// Save the image to the SD card for testing viewing
saveScreen(mImageView.getBitmap());
} catch (IOException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mImageView.postInvalidate();
}
// Not currently used - Harry July 14 2013
private Bitmap cropBitmap(Bitmap bitmap) {
Bitmap result = Bitmap.createBitmap(bitmap, 1, 1, 128, 500);
Log.e("croped",
"w = " + result.getWidth() + " h = " + result.getHeight());
return result;
}
public void saveScreen(Bitmap bitmap) {
Log.e("saveScreen Enter= " + bitmap.getByteCount(),
"w = " + bitmap.getWidth() + " h =" + bitmap.getHeight());
String root = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/images");
myDir.mkdirs();
String fname = "FPCKit.jpg";
File file = new File(myDir, fname);
/*
* boolean done = false; int n = 1; do { String fname = "Image-" + n +
* ".jpg"; file = new File(myDir, fname); if (!file.exists()) { done =
* true; } n++; } while (!done);
*/
try {
FileOutputStream out = new FileOutputStream(file);
// bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
// Bitmap bmp = mImageView.getBitmap();
// bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
Log.e("onSave bytes= " + bitmap.getByteCount(),
"w = " + bitmap.getWidth() + " h =" + bitmap.getHeight());
//This will be as previous version. save entire image.
mImageView.getDrawingCache().compress(Bitmap.CompressFormat.JPEG, 100, out);
// bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
Toast toast = Toast.makeText(ImageCaptureActivity.this,
"Image saved to " + file.getAbsolutePath(),
Toast.LENGTH_SHORT);
toast.show();
} catch (Exception e) {
e.printStackTrace();
Toast toast = Toast.makeText(ImageCaptureActivity.this,
"Exception saving image: " + e.getLocalizedMessage(),
Toast.LENGTH_SHORT);
toast.show();
}
}
}
Related
here is my code :
ImageView mImageView = (ImageView)findViewById(R.id.imageView1);
// Bitmap bmp =drawTextToBitmap(this,R.drawable.man,"Hello Android");
Bitmap bmp =drawTextArrayToBitmap(this,R.drawable.man,"Smile");
mImageView.setImageBitmap(bmp);
now here is my method :
public Bitmap drawTextArrayToBitmap(Context mContext, int resourceId,String mText) {
try {
Resources resources = mContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.rgb(110,110, 110));
paint.setTextSize((int) (12 * scale));
paint.setShadowLayer(1f, 0f, 1f, Color.DKGRAY);
Rect bounds = new Rect();
paint.getTextBounds(mText, 0, mText.length(), bounds);
/* int x = (bitmap.getWidth() - bounds.width())/6;
int y = (bitmap.getHeight() + bounds.height())/5;*/
int x = 100, y = 100;
for(int i=0;i<20;i++)
{
canvas.drawText(mText, x * scale, y * scale, paint);
}
return bitmap;
} catch (Exception e) {
// TODO: handle exception
return null;
}
}
}
I am working on an android application like image filter I want to make an image like this after using a filter over an image
After searching on StackOverflow I got this solution only and this is not like as I want to implement: I got like this
canvas.drawText("This is", 100, 100, mTextPaint);
canvas.drawText("multi-line", 100, 150, mTextPaint);
canvas.drawText("text", 100, 200, mTextPaint);
I do not want to do like this : please help me I would approciate your answers and suggestion
What I Want: I want to add text at bottom of a image which I have chose from either gallery or camera.
Original Image
I added blue color strip to image at bottom
In that strip, I want to add some text exactly in middle.
What's the Problem:
I'm unable to position text exactly in middle of blue color strip.
For different images, text size changes. Some time it is very small, some time it is very big.
What I Tried: My code is like below.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ImageView mImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageView);
}
public void openGallery(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 100);
}
public void openCamera(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 101);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && resultCode == Activity.RESULT_OK) {
if (requestCode == 100) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media
.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
addStampToImage(bitmap);
} else if (requestCode == 101) {
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
addStampToImage(bitmap);
}
}
}
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
Paint pText = new Paint();
pText.setColor(Color.WHITE);
pText.setTextSize((int) (20 * scale));
String text = "Maulik";
/*Rect r = new Rect();
canvas.getClipBounds(r);
int cHeight = r.height();
int cWidth = r.width();
pText.setTextAlign(Paint.Align.LEFT);
pText.getTextBounds(text, 0, text.length(), r);
float x = -r.left;
float y = cHeight / 2f + r.height() / 2f - r.bottom;
int minusSpace = (int) (canvas.getClipBounds().bottom * 0.07);
canvas.drawText(text, 0, canvas.getClipBounds().bottom - minusSpace, pText);*/
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
int x = (newBitmap.getWidth() - bounds.width())/6;
int y = (newBitmap.getHeight() + bounds.height())/5;
canvas.drawText(text, x * scale, y * scale, pText);
mImageView.setImageBitmap(newBitmap);
}
}
Any help will be appreciated!
Updated: 1st Aug 2018
Changes in addStampToImage method.
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Rect textHeightWidth = new Rect();
pText.getTextBounds(fromWhichMode, 0, fromWhichMode.length(), textHeightWidth);
canvas.drawText(textToStamp, (canvas.getWidth() / 2) - (textHeightWidth.width() / 2),
originalBitmap.getHeight() + (extraHeight / 2) + (textHeightWidth.height() / 2),
pText);
Above changes giving me text in middle of blue strip. But core ISSUE remains same. i.e Text size changes with respect to different image sizes.
Check the below code:-
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
String text = "Maulik";
Paint pText = new Paint();
pText.setColor(Color.WHITE);
setTextSizeForWidth(pText,(int) (originalBitmap.getHeight() * 0.10),text);
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
int x= ((newBitmap.getWidth()-(int)pText.measureText(text))/2);
int h=(extraHeight+bounds.height())/2;
int y=(originalBitmap.getHeight()+h);
canvas.drawText(text, x, y, pText);
imageView.setImageBitmap(newBitmap);
}
private void setTextSizeForWidth(Paint paint, float desiredHeight,
String text) {
// Pick a reasonably large value for the test. Larger values produce
// more accurate results, but may cause problems with hardware
// acceleration. But there are workarounds for that, too; refer to
// http://stackoverflow.com/questions/6253528/font-size-too-large-to-fit-in-cache
final float testTextSize = 48f;
// Get the bounds of the text, using our testTextSize.
paint.setTextSize(testTextSize);
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
// Calculate the desired size as a proportion of our testTextSize.
float desiredTextSize = testTextSize * desiredHeight / bounds.height();
// Set the paint for that size.
paint.setTextSize(desiredTextSize);
}
Edit:-
Instead of above addStampToImage method you can also use your updated addStampToImage method like below:-
private void addStampToImage(Bitmap originalBitmap) {
int extraHeight = (int) (originalBitmap.getHeight() * 0.15);
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Resources resources = getResources();
float scale = resources.getDisplayMetrics().density;
String text = "Maulik";
Paint pText = new Paint();
pText.setColor(Color.WHITE);
setTextSizeForWidth(pText,(int) (originalBitmap.getHeight() * 0.10),text);
Rect bounds = new Rect();
pText.getTextBounds(text, 0, text.length(), bounds);
Rect textHeightWidth = new Rect();
pText.getTextBounds(text, 0, text.length(), textHeightWidth);
canvas.drawText(text, (canvas.getWidth() / 2) - (textHeightWidth.width() / 2),
originalBitmap.getHeight() + (extraHeight / 2) + (textHeightWidth.height() / 2),
pText);
imageView.setImageBitmap(newBitmap);
}
try this one i think help to you
/**
* FOR WATER-MARK
*/
public static Bitmap waterMark(Bitmap src, String watermark, Point location, int color, int alpha, int size, boolean underline) {
int[] pixels = new int[100];
//get source image width and height
int widthSreen = src.getWidth(); // 1080L // 1920
int heightScreen = src.getHeight(); // 1343L // 2387
Bitmap result = Bitmap.createBitmap(widthSreen, heightScreen, src.getConfig());
//create canvas object
Canvas canvas = new Canvas(result);
//draw bitmap on canvas
canvas.drawBitmap(src, 0, 0, null);
//create paint object
Paint paint = new Paint();
// //apply color
// paint.setColor(color);
// //set transparency
// paint.setAlpha(alpha);
// //set text size
size = ((widthSreen * 5) / 100);
paint.setTextSize(size);
// paint.setAntiAlias(true);
// //set should be underlined or not
// paint.setUnderlineText(underline);
//
// //draw text on given location
// //canvas.drawText(watermark, w / 4, h / 2, paint);
Paint.FontMetrics fm = new Paint.FontMetrics();
paint.setColor(Color.WHITE);
// paint.setTextSize(18.0f);
paint.getFontMetrics(fm);
int margin = 5;
canvas.drawRect(50 - margin, 50 + fm.top - margin,
50 + paint.measureText(watermark) + margin, 50 + fm.bottom
+ margin, paint);
paint.setColor(Color.RED);
canvas.drawText(watermark, 50, 50, paint);
return result;
}
call this method on your onActivityResult
Bitmap bitmapp = waterMark(bitmap, your_string, p, Color.RED, 90, 90, true);
I am making a camera based application, where I put a rectangular view over the camera.
When I capture an image using new Camera.PictureCallback(), I cropped that image so as it will get the part of the rectangle.
Well, its working fine.
Now I implemented View.OnTouchListener and using that I made the shape movable.
So, I need to capture the image with the final selection of the user, like where they place the rectangle.
Bitmap imageOriginal = BitmapFactory.decodeByteArray(data, 0, data.length); // 2560×1440
float scale = 1280 / 1000;
int left = (int) (scale * (imageOriginal.getWidth() - 250) / 2);
int top = (int) (scale * (imageOriginal.getHeight() - 616) / 2);
int width = (int) (scale * 750);
int height = (int) (scale * 616);
Bitmap imageConverted = Bitmap.createBitmap(imageOriginal, left, top, width, height, null, false);
This is the method i used to crop image.The values are hard corded to find the exact position.
Now i need values for that top ,bottom, height, width with the changing rectangle.
//My customView that used to draw that rectangle
public class CustomView extends View {
private Paint paint = new Paint();
public CustomView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) { // Override the onDraw() Method
super.onDraw(canvas);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
paint.setStrokeWidth(10);
//center
int x0 = canvas.getWidth()/2;
int y0 = canvas.getHeight()/2;
int dx = canvas.getHeight()/3;
int dy = canvas.getHeight()/3;
//draw guide box
canvas.drawRect(x0-dx, y0-dy, x0+dx, y0+dy, paint);
}
}
//my picture callback code
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// Replacing the button after a photho was taken.
// File name of the image that we just took.
fileName = "IMG_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()).toString() + ".jpg";
// Creating the directory where to save the image. Sadly in older
// version of Android we can not get the Media catalog name
File mkDir = new File(sdRoot, dir);
mkDir.mkdirs();
// Main file where to save the data that we recive from the camera
File pictureFile = new File(sdRoot, dir + fileName);
// Cropping image with the corresponding co-ordinates and save in to a file
try {
Bitmap imageOriginal = BitmapFactory.decodeByteArray(data, 0, data.length); // 2560×1440
float scale = 1280 / 1000;
int left = (int) (scale * (imageOriginal.getWidth() - 250) / 2);
int top = (int) (scale * (imageOriginal.getHeight() - 616) / 2);
int width = (int) (scale * 750);
int height = (int) (scale * 616);
Bitmap imageConverted = Bitmap.createBitmap(imageOriginal, left, top, width, height, null, false);
FileOutputStream purge = new FileOutputStream(pictureFile);
imageConverted.compress(Bitmap.CompressFormat.JPEG, 100, purge);
purge.flush();
purge.close();
} catch (FileNotFoundException e) {
Log.d("DG_DEBUG", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage());
}
// Adding Exif data for the orientation.
try {
ProjectManager.getInstance().settings.IMAGE_LOCATION = "/sdcard/" + dir + fileName;
exif = new ExifInterface(ProjectManager.getInstance().settings.IMAGE_LOCATION);
exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" + orientation);
exif.saveAttributes();
mView.saveImage(dir + fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
};
For me, I take a image then crop according to dimension of the selected area of the image..
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap imageOriginal = BitmapFactory.decodeByteArray(data, 0, data.length, null);
int width = imageOriginal.getWidth();
int height = imageOriginal.getHeight(); // for width
int narrowSize = Math.min(width, height); // for height
int differ = (int) Math.abs((imageOriginal.getHeight() - imageOriginal.getWidth()) / 2.0f); // for dimension
width = (width == narrowSize) ? 0 : differ;
height = (width == 0) ? differ : 0;
Matrix rotationMatrix = new Matrix();
rotationMatrix.postRotate(90); // for orientation
Bitmap imageCropped = Bitmap.createBitmap(imageOriginal, width, height, narrowSize, narrowSize, rotationMatrix, false);
}
Capture Image
Output Image
Your rectangle is mCustomView.getWidth()*2/3 pixels wide, and mCustomView.getHeight()*2/3 pixels high, and its left corner is at 1/6 of mCustomView.getWidth(), if I understand your post correctly.
public void onPictureTaken(byte[] data, Camera camera) {
//.../
Bitmap imageOriginal = BitmapFactory.decodeByteArray(data, 0, data.length);
int[] customViewPosition;
mCustomView.getLocationInWindow(customViewPosition);
int[] surfacePosition;
mSurfaceView.getLocationInWindow(surfacePosition);
float scale = imageOriginal.getWidth()/(float)mSurfaceView.getWidth();
int left = (int) scale*(customViewPosition[0] + mCustomView.getWidth()/6F - surfacePosition[0]);
int top = (int) scale*(customViewPosition[1] + mCustomView.getHeight()/6F - surfacePosition[1]);
int width = (int) scale*mCustomView.getWidth()*2/3;
int height = (int) scale*mCustomView.getHeight()*2/3;
Bitmap imageCropped = Bitmap.createBitmap(imageOriginal, left, top, width, height, null, false);
//.../
}
I need your help, if you are kind enough, into an issue that I'm having with my Android app:
I've managed to capture a picture in my MainActivity and display it into an separate activity - PictureActivity. My code is as follows:
In my MainActivity i have
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
/**
* This is called in tap on a graphic element in my MainActivity layout
*/
public void launchCamera(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
Bitmap imageData = null;
if (resultCode == RESULT_OK) {
imageData = (Bitmap) data.getExtras().get("data");
Intent i = new Intent(this, PictureActivity.class);
i.putExtra("captured_picture", imageData);
startActivity(i);
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
Toast.makeText(getApplicationContext(), R.string.picture_capture_error, Toast.LENGTH_SHORT).show();
}
}
}
My PictureActivity looks like this:
public class PictureActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_picture);
Bitmap bitmap = getIntent().getExtras().getParcelable("captured_picture");
ImageView view = (ImageView) findViewById(R.id.preview_photo);
view.setImageBitmap(bitmap);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.image_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
return super.onOptionsItemSelected(item);
}
}
My PictureActivity layout looks like this
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/preview_photo"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
This is how the final result looks so far:
Long story short, these are the things I want to do next:
rotate the picture if the user taps on the middle button from the main action bar
crop the picture if the user taps on the first button from the left
Next, save the image somewhere (in shared preferences or session maybe?) and, aftewords, upload it to a remote server. I say "save the image somewhere" because the user can chose to take a second picture (from a maximum of two) and perform the same action, as above, on it (by taping on the first button from the right, in the main action bar).
What I can't figure out so far is:
how do I know what is the current image (that I see on my screen)
how can I set it's name and it's location where it should be saved to until I upload it to the remote server
how can I manipulate it when I tap on one of the two buttons (crop or rotate)
Sorry for the long post and thank you in advance for your help!
To answer your 3 questions:
The current image you see is in your devices RAM. Its the bitmap object which holds the data.
You have to save the bitmap to your devices storage
you have to transform your bitmap before saving it to storage
Here is some code which might help you:
public static void saveBitmapToFile(Bitmap bitmap, String filename){
FileOutputStream out = null;
try {
out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static Bitmap cropAndRotateBitmap(Bitmap bitmap, Rect cropRect, int rotateByDegrees) {
Log.v(TAG, "cropAndRotateBitmap()");
Log.v(TAG, "bitmap: " + bitmap);
//Log.v(TAG, "orientation: " + orientation);
Log.v(TAG, "degrees: " + rotateByDegrees);
Log.v(TAG, "cropRect: " + cropRect);
int cropRectWidth = cropRect.right - cropRect.left;
int cropRectHeight = cropRect.bottom - cropRect.top;
System.gc();
Bitmap result;
Matrix m = new Matrix();
Canvas canvas = new Canvas();
if (rotateByDegrees == 0) {
result = Bitmap.createBitmap(cropRectWidth, cropRectHeight, Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
m.postTranslate(-cropRect.left, -cropRect.top);
} else if (rotateByDegrees == 90) {
Log.v(TAG, "rotate 90, cropRect: " + cropRect);
result = Bitmap.createBitmap(cropRectHeight, cropRectWidth, Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
m.postTranslate(-cropRect.left, -cropRect.height() - cropRect.top);
m.postRotate(90);
} else if (rotateByDegrees == 180) {
Log.v(TAG, "rotate 180");
result = Bitmap.createBitmap(cropRectWidth, cropRectHeight, Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
m.postTranslate(-cropRect.left - cropRect.width(), -cropRect.height() - cropRect.top);
m.postRotate(180);
} else { // 270
Log.v(TAG, "rotate 270");
result = Bitmap.createBitmap(cropRectHeight, cropRectWidth, Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
m.postTranslate(-cropRect.width() - cropRect.left, -cropRect.top);
m.postRotate(270);
}
Paint whitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
whitePaint.setStyle(Paint.Style.FILL);
whitePaint.setColor(Color.WHITE);
canvas.drawBitmap(bitmap, m, whitePaint);
// canvas.restore();
return result;
}
public static Bitmap rotateBitmap(Bitmap bitmap, int rotateByDegrees) {
Log.v(TAG, "rotateBitmap()");
Log.v(TAG, "degrees: " + rotateByDegrees);
System.gc();
Bitmap result;
Canvas canvas = new Canvas();
if (rotateByDegrees == 0) {
result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
canvas.save();
} else if (rotateByDegrees == 90) {
result = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
canvas.save();
canvas.rotate(90);
canvas.translate(0, -1 * bitmap.getHeight());
} else if (rotateByDegrees == 180) {
result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
canvas.save();
canvas.rotate(180);
canvas.translate(-1 * bitmap.getWidth(), -1 * bitmap.getHeight());
} else { // 270
result = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
canvas.save();
canvas.rotate(270);
canvas.translate(-1 * bitmap.getWidth(), 0);
}
canvas.drawBitmap(bitmap, new Matrix(), null);
canvas.restore();
return result;
}
I'm using the code below. My app was able to draw on the canvas and save it.
But what I want to do is make an image as the background of the canvas so when I save it, it will look like an image with the user's drawing on top of it.
Thank you so much for any help! :)
#Override
public void run() {
Canvas canvas = null;
while (_run){
if(isDrawing == true){
try{
canvas = mSurfaceHolder.lockCanvas(null);
if(mBitmap == null){
mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);
}
final Canvas c = new Canvas (mBitmap);
c.drawColor(0, PorterDuff.Mode.CLEAR);
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
canvas.drawColor(0xffffffff);
commandManager.executeAll(c,previewDoneHandler);
previewPath.draw(c);
canvas.drawBitmap (mBitmap, 0, 0,null);
} finally {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
Try this stuff,
This will return a Bitmap that will be a Merged one of two Bitmap Images, also it will save in the SDCard.
public Bitmap combineImages(Bitmap c, Bitmap s) {
Bitmap cs = null;
int width, height = 0;
if (c.getWidth() > s.getWidth()) {
width = c.getWidth();
height = c.getHeight();
} else {
width = s.getWidth() + s.getWidth();
height = c.getHeight();
}
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(c, 0, 0, null);
comboImage.drawBitmap(s, 100, 300, null);
/******
*
* Write file to SDCard
*
* ****/
String tmpImg = String.valueOf(System.currentTimeMillis()) + ".png";
OutputStream os = null;
try {
os = new FileOutputStream(Environment.getExternalStorageDirectory()
+ "/"+tmpImg);
cs.compress(CompressFormat.PNG, 100, os);
} catch (IOException e) {
Log.e("combineImages", "problem combining images", e);
}
return cs;
}
For any view that you are creating, you can create a bitmap of what it is currently displaying.
use:
view.setDrawingCacheEnabled(true);
Bitmap bitmap=view.getDrawingCache();
Does this help you in achieving what you want ?
*be sure to recycle these bitmaps when you are done.
bitmap.recycle();