Add plain text to picture taken from camera intent - android

I have application which uses camera intent and saves picture taken into specific folder. Now i am missing one more functionality and that is that after picture is taken i should add plain text (timestamp, few more infos on picture lower/upper border) and save it.
How to achieve this? My code is below
public void takePicture( View view)
{
Intent intentCamera = new Intent();
intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
File photofile = null;
try{
photofile=createImageFile();
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photofile));
startActivityForResult(intentCamera, ActivityStartamera);
//Toast.makeText(this,Uri.fromFile(photofile).toString(), Toast.LENGTH_LONG).show();
}
catch (IOException e)
{
e.printStackTrace();
Toast.makeText(this, "Error happened", Toast.LENGTH_LONG).show();
imageFileName="";
}
}
protected void onActivityResult (int requestCode, int resultCode, Intent data)
{
if(requestCode == ActivityStartamera && resultCode == RESULT_OK)
{
//
//here i should add plain text to taken picture
//
Toast.makeText(this, "Picture taken", Toast.LENGTH_LONG).show();
}
else{
image.delete();
}
}
File createImageFile () throws IOException{
String timeStamp = new SimpleDateFormat("MMyyyydd_HHmmss").format(new Date());
imageFileName = "picture_"+timeStamp;
storage = Environment.getExternalStoragePublicDirectory("PicturesForApp");
if (!storage.exists())
{
Toast.makeText(this, "Folder made for pictures", Toast.LENGTH_LONG).show();
storage.mkdirs();
}
image = new File(storage + "/" +imageFileName +".jpg");
return image;
}
I have tried something like this but was unsucesfull.

Please use this method I am sure it will help you.
public Bitmap addTextToImage(Bitmap src, String textToAddOnImage, int x, int y, int color, int alpha, int size, boolean underline) {
int w = src.getWidth();
int h = src.getHeight();
Bitmap result = Bitmap.createBitmap(w, h, src.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(src, 0, 0, null);
Paint paint = new Paint();
paint.setColor(color);
paint.setAlpha(alpha);
paint.setTextSize(size);
paint.setAntiAlias(true);
paint.setUnderlineText(underline);
canvas.drawText(textToAddOnImage, x, y, paint);
return result;
}
Call this method like this
// use this bitmap to show in imageView and you can also save the bitmap.
Bitmap bmp = addTextToImage(srcBitmap, "Mustanser Iqbal", 200, 200, Color.GREEN, 80, 24, false);
File f = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + fileName + ".png");
FileOutputStream fos = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);

Related

Bitmap Image Saved to Internal Storage is Corrupt

I want to design an app that generates a QR code and gives the user the possibility to save the generated image to their internal storage only. I successfully generate the bitmap and save it as .PNG image, but when I try to open it from the gallery it appears broken or corrupt.
Below is the code to generate the bitmap and display it on an ImageView(qrCode):
bitmap = encodeAsBitmap(value);
qrCode.setImageBitmap(bitmap);
Bitmap encodeAsBitmap(String str) throws WriterException {
BitMatrix result;
try {
result = new MultiFormatWriter().encode(str,
BarcodeFormat.QR_CODE, WIDTH, WIDTH, null);
} catch (IllegalArgumentException iae) {
// Unsupported format
return null;
}
int w = result.getWidth();
int h = result.getHeight();
int[] pixels = new int[w * h];
for (int y = 0; y < h; y++) {
int offset = y * w;
for (int x = 0; x < w; x++) {
pixels[offset + x] = result.get(x, y) ? getResources().getColor(R.color.colorBlack) :
getResources().getColor(R.color.colorWhite);
}
}
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, 500, 0, 0, w, h);
return bitmap;
}
It works perfectly up to this level. The user can then click a button in order to save this image to their device's internal storage, thanks to the below method:
public void onClickSaveCode(View view) {
String title = getResources().getString(R.string.saved_image_title_prepend) + stringDate;
String format = getResources().getString(R.string.saved_image_format);
String directory = getResources().getString(R.string.saved_image_directory);
// Method call to save image
saveImageToInternalStorage(bitmap, directory, title, format);
}
public boolean saveImageToInternalStorage(Bitmap bitmap, String directory, String title, String format) {
ContextWrapper contextWrapper = new ContextWrapper(getApplicationContext());
File imageDirectory = contextWrapper.getDir(directory, Context.MODE_WORLD_READABLE);
File path = new File(imageDirectory, title + format);
try {
FileOutputStream fos = new FileOutputStream(path);
// Use the compress method on the Bitmap object to write image to the OutputStream
bitmap.compress(Bitmap.CompressFormat.PNG, QUALITY, fos);
fos.close();
new SingleMediaScanner(this, path);
Toast.makeText(this, getString(R.string.save_success), Toast.LENGTH_LONG).show();
return true;
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, getString(R.string.save_failure), Toast.LENGTH_LONG).show();
return false;
}
}
And finally below is the MediaScannerConnection class to scan for all images saved to the device and display them in the gallery:
public class SingleMediaScanner implements MediaScannerConnectionClient {
private MediaScannerConnection mSC;
private File file;
public SingleMediaScanner(Context context, File f) {
file = f;
mSC = new MediaScannerConnection(context, this);
mSC.connect();
}
#Override
public void onMediaScannerConnected() {
mSC.scanFile(file.getAbsolutePath(), null);
}
#Override
public void onScanCompleted(String path, Uri uri) {
mSC.disconnect();
}
}
The images are saved, yet they appear in the gallery as broken files.
Any help will be greatly appreciated.
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
string filePath = System.IO.Path.Combine(path, "compressed.png");
//Bitmap bmp = ((BitmapDrawable)imgV.Drawable).Bitmap;
Bitmap b = newBitmap;
FileStream ms = new FileStream(filePath, FileMode.Create);
//FileOutputStream fos = new FileOutputStream(filePath,true);
await b.CompressAsync(Bitmap.CompressFormat.Png, 100, ms);
ms.Close();
//ByteArrayOutputStream opstream = new ByteArrayOutputStream();
//b.Compress(Bitmap.CompressFormat.Png, 100, opstream);
//byte[] bytArray = opstream.ToByteArray();
Toast.MakeText(Application.Context, "Compressed : " , ToastLength.Short).Show();
imgCompress.SetImageBitmap(b);

Why I get defected image from ImageCropper( android wallpaper app)?

I am making android wallpaper app. At the start, I didn't use imagecropper and background image for android was very perfect. Then I wanted to add ImageCropper function and I noticed the problem: Image that I got from ImageCropper was very defected and bad quality. I am sure that the problem is here: (Performcrop method(starts activity for result))
public void performCrop(Uri picUri, Bitmap qq){
try {
utils = new Utils(getApplicationContext());
int height, width;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
height = size.y;
width = size.x;
File f= new File(utils.saveImageToSDCard(qq));
f.createNewFile();
Intent cropIntent = new Intent("com.android.camera.action.CROP");
//indicate image type and Uri
cropIntent.setDataAndType(picUri, "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
//indicate X and Y
cropIntent.putExtra("outputX", width);
cropIntent.putExtra("outputY", height);
//retrieve data on return
cropIntent.putExtra("return-data", true);
//start the activity - we handle returning in onActivityResult
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, picUri.fromFile(f));
startActivityForResult(cropIntent, 1);
}
catch(ActivityNotFoundException anfe){
//display an error message
String errorMessage = "Whoops - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
} catch (IOException e) {
e.printStackTrace();
}
}
OnActivityResult:
#Override
protected void onActivityResult(int requestCode,int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1) {
//get the cropped bitmap
if (data != null) {
Bundle extras = data.getExtras();
int height, width;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
height = size.y;
width = size.x;
utils = new Utils(getApplicationContext());
Bitmap thePic = (Bitmap) (extras.getParcelable("data"));
Bitmap krutoi = Bitmap.createBitmap(thePic, 0, 0, width, height);
utils.setAsWallpaper(krutoi);
}
}
}
Here OnClick listener for SetWallpaperButton:
llDownloadWallpaper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
utils = new Utils(getApplicationContext());
bitmap = ((BitmapDrawable) fullImageView.getDrawable())
.getBitmap();
utils.saveImageToSDCard(bitmap);
}
});
saveImageToSdCard(Utils.java):
public String saveImageToSDCard(Bitmap bitmap) {
File myDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
pref.getGalleryName());
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Wallpaper-" + n + ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
Toast.makeText(
_context,
_context.getString(R.string.toast_saved).replace("#",
"\"" + pref.getGalleryName() + "\""),
Toast.LENGTH_SHORT).show();
Log.d(TAG, "Wallpaper saved to: " + file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(_context,
_context.getString(R.string.toast_saved_failed),
Toast.LENGTH_SHORT).show();
}
return file.getAbsolutePath();
}
setAsWallpaper(Utils.java):
public void setAsWallpaper(Bitmap bitmap) {
try {
WallpaperManager wm = WallpaperManager.getInstance(_context);
wm.setBitmap(bitmap);
Toast.makeText(_context,
_context.getString(R.string.toast_wallpaper_set),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(_context,
_context.getString(R.string.toast_wallpaper_set_failed),
Toast.LENGTH_SHORT).show();
}
}

Android Tesseract taking too long and returning absurd data

I'm building an android tesseract app. It was reading the data fine until I was taking photos from the default camera app. Now, I needed to implement my own custom camera, that caused it to start giving wrong result.
public class getButtonClicked implements View.OnClickListener{
public void onClick(View arg0) {
DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/MyOCRApp/";
File tessdata = new File(DATA_PATH);
if (!tessdata.isDirectory()){
throw new IllegalArgumentException("Data path must contain subfolder tessdata!");
}
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(DATA_PATH, lang);
if (newImg == null){
baseApi.setImage(imageBitmap);
}
else{
baseApi.setImage(newImg);
}
String recognizedText = baseApi.getUTF8Text();
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(context);
// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage("Recognized Text:\n\n" + recognizedText);
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
dialog.show();
//baseApi.end();
}
}
This is the code that calls the tesseract APIs.
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d("Error creating file" ,"!");
return;
}
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Notice that width and height are reversed
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
MainActivity.imageBitmap = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
}else{// LANDSCAPE MODE
//No need to reverse width and height
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true);
MainActivity.imageBitmap = scaled;
}
Calendar c = Calendar.getInstance();
String time = Integer.toString(c.get(Calendar.DATE));
//MediaStore.Images.Media.insertImage(getContentResolver(), MainActivity.imageBitmap, time+"MyOCR", "Hello!!");
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/MyOCRApp");
if (! myDir.exists()){
if (! myDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return;
}
}
String fname = "Image-" +time+ ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
MainActivity.imageBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
MediaStore.Images.Media.insertImage(getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
} catch (Exception e) {
e.printStackTrace();
}
surfaceDestroyed(mSurfaceHolder);
}
};
This is the code in my camera class. I even debugged and checked that the picture was perfectly fine, when the tesseract APIs are called. I can't post photos, otherwise I have posted one. What should I do??
I am experimenting with tesseract on android as well. Try to rescale your image. An image taken by the camera activity maybe to big. Additionaly you probably have to pre-process the image (contrast, horizontal alignment of text, ...)

Save cameraPreview with overlay image

I'm using Google's CameraPreview sample demo. Here, I have the cameraPreview, and an overlayed image over cameraPreview.
When I take the photo, only the cameraPreview is saved, but I need the overlay image to be saved too over the cameraPreview.
This is the way I save cameraPreview's photo, but I need to know what would be the best way for overlaying booth images and save them into one.
public void onPictureTaken(byte[] data, Camera camera) {
String photoPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/miFoto.jpg";
try {
FileOutputStream fos = new FileOutputStream(photoPath);
fos.write(data);
fos.close();
} catch (IOException e) {
Toast.makeText(this, "Pic not saved", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, "Pic saved in: " + photoPath, Toast.LENGTH_SHORT).show();
camera.startPreview();
}
I finally made it this way:
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap cameraScaledBitmap = Bitmap.createScaledBitmap(cameraBitmap, 1280, 720, true);
int wid = cameraScaledBitmap.getWidth();
int hgt = cameraScaledBitmap.getHeight();
Bitmap newImage = Bitmap.createBitmap(wid, hgt, Bitmap.Config.ARGB_8888);
Bitmap overlayScaledBitmap = Bitmap.createScaledBitmap(overlayBitmap, wid, hgt, true);
Canvas canvas = new Canvas(newImage);
canvas.drawBitmap(cameraScaledBitmap , 0, 0, null);
canvas.drawBitmap(overlayScaledBitmap , 0, 0, null);
File storagePath = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
storagePath.mkdirs();
String finalName = Long.toString(System.currentTimeMillis());
File myImage = new File(storagePath, finalName + ".jpg");
String photoPath = Environment.getExternalStorageDirectory().getAbsolutePath() +"/" + finalName + ".jpg";
try {
FileOutputStream fos = new FileOutputStream(myImage);
newImage.compress(Bitmap.CompressFormat.JPEG, 80, fos);
fos.close();
} catch (IOException e) {
Toast.makeText(this, "Pic not saved", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, "Pic saved in: " + photoPath, Toast.LENGTH_SHORT).show();
camera.startPreview();
newImage.recycle();
newImage = null;
cameraBitmap.recycle();
cameraBitmap = null;
}

I'm saving the photo on the android gallery but the photo has a delay to save

I want to take a picture with my app and send it to Instagram, but I'm with some problem because when I shot the photo my app has some delay to save.
My app is doing in this way
First I take a picture with my app and save this picture in the gallery.
After the user will approve or not the image. If he approves he clicks on a button and send it to Instagram, but I don't know why the app is taking some seconds to save my image.
My method to get the image I want to use is to get the last picture I saved on my folder's gallery.
This is the code I call to take a picture.
camera = cameraSurfaceView.getCamera();
camera.takePicture(new ShutterCallback() {
#Override
public void onShutter() {
AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mgr.playSoundEffect(AudioManager.FLAG_PLAY_SOUND);
}
}, null, new HandlePictureStorage(preview,cameraSurfaceView.getFront()));
imageSelected = false;
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
Here is the class I use to get the picture and save
public class HandlePictureStorage implements PictureCallback {
FrameLayout preview;
int wid = 0;
Bitmap bitmapFinal;
boolean front;
File storagePath = new File(Environment.getExternalStorageDirectory() + "/Tubagram/");
public HandlePictureStorage(FrameLayout preview, boolean front){
this.preview = preview;
this.front = front;
}
#Override
public void onPictureTaken(byte[] picture, Camera camera) {
Matrix matrix = new Matrix();
if (front){
matrix.postRotate(270);
}else{
matrix.postRotate(90);
}
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(picture, 0, picture.length);
wid = cameraBitmap.getWidth();
Bitmap scaledBitmap = Bitmap.createScaledBitmap(cameraBitmap, wid, wid, true);
Bitmap imagemRotacionada = Bitmap.createBitmap(scaledBitmap,0,0,scaledBitmap.getWidth(),scaledBitmap.getHeight(),matrix,true);
Bitmap newImage = Bitmap.createBitmap
(612, 612, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newImage);
canvas.drawBitmap(imagemRotacionada, 0f, 0f, null);
Drawable drawable = preview.getForeground();
drawable.setBounds(0, 0, 612, 612);
drawable.draw(canvas);
File myImage = new File(storagePath,"TUBAGRAM_" + System.currentTimeMillis() +".png");
try
{
FileOutputStream out = new FileOutputStream(myImage);
newImage.compress(Bitmap.CompressFormat.PNG, 100, out);
bitmapFinal = newImage;
out.flush();
out.close();
Log.i("Imagem Tubagram salva em ", ""+ myImage);
}
catch(FileNotFoundException e)
{
Log.d("In Saving File", e + "");
}
catch(IOException e)
{
Log.d("In Saving File", e + "");
}
drawable = null;
// newImage.recycle();
newImage = null;
cameraBitmap.recycle();
cameraBitmap = null;
}
And here is the code when I accept the photo and send to Instagram
if (verificaInstagram()){
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("image/*");
Cursor c1 = pickLastPhotoAlbum();
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+Environment.getExternalStorageDirectory()+ "/Tubagram/" + c1.getString(1)+".png"));
shareIntent.setPackage("com.instagram.android");
c1.close();
startActivity(shareIntent);
}else{
Toast.makeText(v.getContext(), "Você não possui o Instagram no seu smartphone!", Toast.LENGTH_SHORT).show();
}
Anyone can help me with this?
Ok. I solved this question by doing this.
The class I use to save the picture I changed this part...
FileOutputStream out = new FileOutputStream(myImage);
newImage.compress(Bitmap.CompressFormat.PNG, 100, out);
bitmapFinal = newImage;
out.flush();
and now I use this one...
String nomeImagem = "TUBAGRAM_" + System.currentTimeMillis();
url = MediaStore.Images.Media.insertImage(preview.getContext().getContentResolver(), newImage ,nomeImagem, null);
And the code I use to accept the photo and send to Instagram I changed to
caminhoImagens = getRealPathFromURI(Uri.parse(hps.getUrl()));
Log.i("Caminho imagem: ", caminhoImagens);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + caminhoImagens));
shareIntent.setPackage("com.instagram.android");
And retire the cursor.

Categories

Resources