canvas.drawText text to EditText's place - java

I have movable EditText on ImageView and save button. On click save button app should draw text from EditText to the image. For now, app is working but doesn't draw exactly to EditText's place. I need to draw precisely to EditText's place, it should look like EditText pasting text.
this is a code:
public void saveButtonClicked() {
if (!textEditText.getText().toString().equals("")) {
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), mCroppedImageUris.get(mCurrentImageIndex));
mCropImageView.setImageBitmap(textAsBitmap(bitmap, textEditText.getText().toString(), 25f, mTextColor));
} catch (IOException e) {
e.printStackTrace();
}
}
}
private Bitmap textAsBitmap(Bitmap image, String text,
float textSize, int textColor) {
Paint paint = new Paint();
paint.setTextSize(textSize);
paint.setColor(textColor);
paint.setAntiAlias(true);
Bitmap newMapBitmap = image.copy(Bitmap.Config.ARGB_8888, true);
try {
Canvas canvas = new Canvas(newMapBitmap);
int[] location = new int[2];
addTextLayout.getLocationOnScreen(location);
float x = (float) (location[0] / 2.1);
float y = (float) (location[1] / 3.1);
canvas.drawText(text, x, y, paint);
} catch (Exception e) {
Log.e("textAsBitmap", e.getMessage());
}
String root = Environment.getExternalStorageDirectory().toString();
File folder = new File(root + Constants.pdfDirectory);
String path = mCroppedImageUris.get(mCurrentImageIndex).getPath();
String filename = "add_text_im";
if (path != null) {
filename = "added_text_" + FileUtils.getFileName(path);
}
File file = new File(folder, filename);
try {
FileOutputStream out = new FileOutputStream(file);
newMapBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
setUpdatedImage(Uri.fromFile(file));
out.flush();
out.close();
} catch (Exception e) {`your text`
e.printStackTrace();
}
return newMapBitmap;
}

Related

Saving a canvas larger than the physical screen

I'm dynamically drawing a some Image, Text through custom view where user can move text up/down left/right also zoom in/out but I would like to save the whole view as Image.I know I can save image but I need it to be in a higher resolution than the actual screen I'm capturing it on.
I am saving image using
File file = new File(imagePath);
try {
FileOutputStream out = new FileOutputStream(file, false);
if (parentView != null) {
parentView.setDrawingCacheEnabled(true);
Bitmap drawingCache = saveSettings.isTransparencyEnabled()
? BitmapUtil.removeTransparency(parentView.getDrawingCache())
: parentView.getDrawingCache();
drawingCache.compress(saveSettings.getCompressFormat(), saveSettings.getCompressQuality(), out);
}
out.flush();
out.close();
Log.d(TAG, "Filed Saved Successfully");
return null;
} catch (Exception e) {
FirebaseCrashlytics.getInstance().recordException(e);
e.printStackTrace();
Log.d(TAG, "Failed to save File");
return e;
}
Using above saving functionality image quality is very poor. I need to very high-resolution image.
Please try this way may help you
class MyActivity extends Activity {
private View rootLayoutContainerView;
private int imageWidth;
private int imageHeight;
private int screenLayoutWidth;
private int screenLayoutHeight;
public final void nextToOverlay() {
Bitmap result = Bitmap.createBitmap(this.screenLayoutWidth, this.screenLayoutHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
rootLayoutContainerView.draw(canvas);
result = resizeBitmapFitXY(imageWidth, imageHeight, result);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
result.compress(Bitmap.CompressFormat.PNG, 100, bytes);
File file = getimagePath((Context)this, "framelayer");
try {
FileOutputStream fo = new FileOutputStream(file);
fo.write(bytes.toByteArray());
fo.flush();
fo.close();
} catch (IOException var6) {
var6.printStackTrace();
}
}
public final Bitmap resizeBitmapFitXY(int width, int height,Bitmap bitmap) {
Bitmap background = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
float originalWidth = (float)bitmap.getWidth();
float originalHeight = (float)bitmap.getHeight();
Canvas canvas = new Canvas(background);
float scale = 0.0F;
float xTranslation = 0.0F;
float yTranslation = 0.0F;
if (originalWidth > originalHeight) {
scale = (float)height / originalHeight;
xTranslation = ((float)width - originalWidth * scale) / 2.0F;
} else {
scale = (float)width / originalWidth;
yTranslation = ((float)height - originalHeight * scale) / 2.0F;
}
Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);
Paint paint = new Paint();
paint.setFilterBitmap(true);
canvas.drawBitmap(bitmap, transformation, paint);
return background;
}
public File getimagePath(Context context,String name) {
File mTranscodeOutputFile = null;
try {
File outputDir = new File(context.getExternalFilesDir(null), "image");
if (!outputDir.exists()) {
outputDir.mkdir();
}
mTranscodeOutputFile = new File(outputDir, name + ".jpg");
} catch (Exception var5) {
}
return mTranscodeOutputFile;
}
}

Weird behaviour when overlaying PNGs

I want to put this image on top of this image.
This is my code:
public class ImageOverlayTest {
public static final String IMAGE_SOURCE_PATH = "src/main/resources/META-INF/resources/images/chess-sources/";
public static final String IMAGE_DEST_PATH = "src/main/resources/META-INF/resources/images/games/";
public static void main(String[] args) {
BufferedImage bgImage = readImage("board", "png");
BufferedImage fgImage = readImage("bb", "png");
BufferedImage overlayedImage = overlayImages(bgImage, fgImage);
writeImage(overlayedImage, "result", "png");
}
public static BufferedImage overlayImages(BufferedImage background,
BufferedImage foreground) {
Graphics2D g = background.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(background, 0, 0, null);
g.drawImage(foreground, 0, 0, null);
g.dispose();
return background;
}
public static BufferedImage readImage(String fileNameWithoutExtension, String extension) {
BufferedImage img = null;
try {
String path = IMAGE_SOURCE_PATH + fileNameWithoutExtension + "." + extension;
img = ImageIO.read(new File(path));
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
public static void writeImage(BufferedImage img, String fileNameWithoutExtension,
String extension) {
try {
String path = IMAGE_DEST_PATH + fileNameWithoutExtension + "." + extension;
File outputFile = new File(path);
ImageIO.write(img, extension, outputFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Mainly taken from here.
The result looks like this:
What is going wrong? Why is it not renderig the top image the same way as when you look at it individually? What can I do to fix that?
Something about the color profile of the background image must have been wrong. I converted it to jpg and back to png using GIMP, now it's working fine ;)

Is it possible to detect if document has been successfully printed?

I want to detect if the printer printed the document (or image it doesn't matter) successfully or there was a paper jam or some kind of an error. The code I've written using JavaFX only sends the job to the printer and that's all. Is it not possible to retrieve printer status or am I missing something?
Here's the code:
public static class Printable implements Runnable
{
#Override
public void run()
{
try (InputStream is = App.class.getResourceAsStream("/pdf-sample.pdf"))
{
PDDocument pdf = PDDocument.load(is);
PDFRenderer pdfRenderer = new PDFRenderer(pdf);
Printer printer = null;
ObservableSet<Printer> allPrinters = Printer.getAllPrinters();
for (Printer p : allPrinters)
{
System.out.println(p.getName());
if (p.getName().equalsIgnoreCase("Xerox WorkCentre 3210/3220 Class Driver"))
{
printer = p;
}
}
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.DEFAULT);
PrinterJob job = PrinterJob.createPrinterJob(printer);
System.out.println("Chose: " + job.getPrinter().getName());
if (job != null)
{
boolean success = true;
for (int pageNumber = 0; pageNumber < pdf.getNumberOfPages(); ++pageNumber)
{
// suffix in filename will be used as the file format
// ImageIOUtil.writeImage(bim, pdfFilename + "-" + (page+1) + ".png", 300);
PDPage page = pdf.getPage(pageNumber);
PDRectangle bounds = page.getBBox();
int width = (int) bounds.getWidth();
int height = (int) bounds.getHeight();
System.out.println(width + ", " + height);
BufferedImage bim = pdfRenderer.renderImageWithDPI(pageNumber, 600, ImageType.RGB);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (ImageIOUtil.writeImage(bim, "png", baos))
{
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
BufferedImage bufferedImage = ImageIO.read(bais);
BufferedImage bImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
bImg.createGraphics().drawImage(bufferedImage, 0, 0, null);
javafx.scene.image.Image fxImg = SwingFXUtils.toFXImage(bImg, null);
ImageView imageView = new ImageView(fxImg);
success = success & job.printPage(imageView);
// if (success)
// {
// job.endJob();
// }
while (job.getJobStatus().equals(JobStatus.PRINTING))
{
Thread.sleep(500);
System.out.println("Printing...");
}
Thread.sleep(1000);
System.out.println(job.getJobStatus());
}
}
if (success)
{
job.endJob();
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

Visual signature with pdfbox 1.8.8

I'm trying to produce PDF with visual signature and pdfbox. I have two streams and it seems that pdfbox can deal only with files. I didn't manage to make it work without three temporary files. I can see from here that API has changed, but still it deals with files.
public void signPdf(InputStream originalPdf, OutputStream signedPdf,
InputStream image, float x, float y,
String name, String location, String reason) {
File temp = null;
File temp2 = null;
File scratchFile = null;
RandomAccessFile randomAccessFile = null;
OutputStream tempOut = null;
InputStream tempIn = null;
try {
/* Copy original to temporary file */
temp = File.createTempFile("signed1", ".tmp");
tempOut = new FileOutputStream(temp);
copyStream(originalPdf, tempOut);
tempOut.close();
/* Read temporary file to second temporary file and stream */
tempIn = new FileInputStream(temp);
temp2 = File.createTempFile("signed2", ".tmp");
tempOut = new FileOutputStream(temp2);
copyStream(tempIn, tempOut);
tempIn.close();
tempIn = new FileInputStream(temp2);
scratchFile = File.createTempFile("signed3", ".bin");
randomAccessFile = new RandomAccessFile(scratchFile, "rw");
/* Read temporary file */
PDDocument document = PDDocument.load(temp, randomAccessFile);
document.getCurrentAccessPermission().setCanModify(false);
PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setName(name);
signature.setLocation(location);
signature.setReason(reason);
signature.setSignDate(Calendar.getInstance());
PDVisibleSignDesigner signatureDesigner = new PDVisibleSignDesigner(
document, image, document.getNumberOfPages());
signatureDesigner.xAxis(250).yAxis(60).zoom(-90).signatureFieldName("signature");
PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
signatureProperties.signerName(name).signerLocation(location)
.signatureReason(reason).preferredSize(0).page(1)
.visualSignEnabled(true).setPdVisibleSignature(signatureDesigner)
.buildSignature();
SignatureOptions options = new SignatureOptions();
options.setVisualSignature(signatureProperties);
document.addSignature(signature, dataSigner, options);
/* Sign */
document.saveIncremental(tempIn, tempOut);
document.close();
tempIn.close();
/* Copy temporary file to an output stream */
tempIn = new FileInputStream(temp2);
copyStream(tempIn, signedPdf);
} catch (IOException e) {
logger.error("PDF signing failure", e);
} catch (COSVisitorException e) {
logger.error("PDF creation failure", e);
} catch (SignatureException e) {
logger.error("PDF signing failure", e);
} finally {
closeStream(originalPdf);
closeStream(signedPdf);
closeStream(randomAccessFile);
closeStream(tempOut);
deleteTempFile(temp);
deleteTempFile(temp2);
deleteTempFile(scratchFile);
}
}
private void deleteTempFile(File tempFile) {
if (tempFile != null && tempFile.exists() && !tempFile.delete()) {
tempFile.deleteOnExit();
}
}
private void closeStream(Closeable is) {
if (is!= null) {
try {
is.close();
} catch (IOException e) {
logger.error("failure", e);
}
}
}
private void copyStream(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int c;
while ((c = is.read(buffer)) != -1) {
os.write(buffer, 0, c);
}
is.close();
}
Apart from file madness I don't see any text on the signature. This is how result looks like:
and this is how it looks, when I do similar thing with itext library
Why name, location and reason missing from the visual signature representation? How can I fix that?
Why name, location and reason missing from the visual signature representation?
They are not there because they are not drawn.
The default way of iText to represent a visualized signature is by adding those information to the visualization.
The default way of PDFBox' PDVisibleSigBuilder to represent a visualized signature is without such information.
Neither is wrong or right, both merely are defaults.
The canonical place where people shall look for such information is the signature panel after all.
How can I fix that?
The actual contents of the signature visualization are created by a PDVisibleSigBuilder instance during signatureProperties.buildSignature():
public void buildSignature() throws IOException
{
PDFTemplateBuilder builder = new PDVisibleSigBuilder();
PDFTemplateCreator creator = new PDFTemplateCreator(builder);
setVisibleSignature(creator.buildPDF(getPdVisibleSignature()));
}
Thus, by replacing
signatureProperties.signerName(name).signerLocation(location)
.signatureReason(reason).preferredSize(0).page(1)
.visualSignEnabled(true).setPdVisibleSignature(signatureDesigner)
.buildSignature();
in your code by
signatureProperties.signerName(name).signerLocation(location)
.signatureReason(reason).preferredSize(0).page(1)
.visualSignEnabled(true).setPdVisibleSignature(signatureDesigner);
PDFTemplateBuilder builder = new ExtSigBuilder();
PDFTemplateCreator creator = new PDFTemplateCreator(builder);
signatureProperties.setVisibleSignature(creator.buildPDF(signatureProperties.getPdVisibleSignature()));
for a customized version ExtSigBuilder of this PDVisibleSigBuilder class, you can draw anything you want there, e.g.:
class ExtSigBuilder extends PDVisibleSigBuilder
{
String fontName;
public void createImageForm(PDResources imageFormResources, PDResources innerFormResource,
PDStream imageFormStream, PDRectangle formrect, AffineTransform affineTransform, PDJpeg img)
throws IOException
{
super.createImageForm(imageFormResources, innerFormResource, imageFormStream, formrect, affineTransform, img);
PDFont font = PDType1Font.HELVETICA;
fontName = getStructure().getImageForm().getResources().addFont(font);
logger.info("Added font to image form: " + fontName);
}
public void injectAppearanceStreams(PDStream holderFormStream, PDStream innterFormStream, PDStream imageFormStream,
String imageObjectName, String imageName, String innerFormName, PDVisibleSignDesigner properties)
throws IOException
{
super.injectAppearanceStreams(holderFormStream, innterFormStream, imageFormStream, imageObjectName, imageName, innerFormName, properties);
String imgFormComment = "q " + 100 + " 0 0 50 0 0 cm /" + imageName + " Do Q\n";
String text = "BT /" + fontName + " 10 Tf (Hello) Tj ET\n";
appendRawCommands(getStructure().getImageFormStream().createOutputStream(), imgFormComment + text);
logger.info("Added text commands to image form: " + text);
}
}
writes "Hello" in Helvetica at size 10 atop the lower left of the image form (the form actually displaying something).
PS: In my opinion the object oriented structure behind this should be completely overhauled.
Display the text over the signatory some time it doesn't look nice. For me, I create new image base on the text that I want to display. And merge it with the signatory image. I can add background for signatory image (company name watermark)
Here is the code create new signatory image with text and background:
public class ImageSignatory {
public static void main(String[] args) {
DateFormat df = new SimpleDateFormat("MM.dd.yyyy");
Date today = Calendar.getInstance().getTime();
String reportDate = df.format(today);
String text = "Signature eletronic Company AA DUC NGUYEN - Date " + reportDate;
String background = "background.png";
String signImage = "sign.jpg";
String textImage = createImageFromText(text);
String imageResultURL = null ;
try {
String mergedImage = mergeTwoImage(signImage, textImage);
imageResultURL = addBackgroundToImage(background, mergedImage);
} catch (Exception ex) {
}
}
public static String StringDivider(String s) {
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + 30)) != -1) {
sb.replace(i, i + 1, "\n");
}
return sb.toString();
}
public static BufferedImage toBufferedImage(Image img) {
if (img instanceof BufferedImage) {
return (BufferedImage) img;
}
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
return bimage;
}
public static String addBackgroundToImage(String backgroundPATH, String imagePath) {
try {
String imageResult = "result.jpg";
Image backgroundImage = ImageIO.read(new File(backgroundPATH));
int width = backgroundImage.getWidth(null);
int height = backgroundImage.getHeight(null);
Image signAndText = ImageIO.read(new File(imagePath));
signAndText = signAndText.getScaledInstance(width, height, Image.SCALE_SMOOTH);
signAndText = toBufferedImage(signAndText);
BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g2 = combined.getGraphics();
g2.drawImage(backgroundImage, 0, 0, null);
g2.drawImage(signAndText, 0, 0, null);
g2.dispose();
ImageIO.write(combined, "JPG", new File(imageResult));
return imageResult;
} catch (IOException ex) {
return null;
}
}
public static String mergeTwoImage(String first, String second) {
try {
String tempFileName = "merged_image.png";
Image signatoryImage = ImageIO.read(new File(first));
Image addtionalTextImage = ImageIO.read(new File(second));
float ratio = (float) signatoryImage.getWidth(null) / (float) addtionalTextImage.getWidth(null);
addtionalTextImage = addtionalTextImage.getScaledInstance((int) (ratio * (float) addtionalTextImage.getWidth(null)), (int) (ratio * (float) addtionalTextImage.getHeight(null)), Image.SCALE_SMOOTH);
addtionalTextImage = toBufferedImage(addtionalTextImage);
BufferedImage combinedTemp = new BufferedImage(signatoryImage.getWidth(null), signatoryImage.getHeight(null) + (int) (ratio * (float) addtionalTextImage.getHeight(null)), BufferedImage.TYPE_INT_ARGB);
Graphics g = combinedTemp.getGraphics();
g.drawImage(signatoryImage, 0, 0, null);
g.drawImage(addtionalTextImage, 0, signatoryImage.getHeight(null), null);
g.dispose();
ImageIO.write(combinedTemp, "PNG", new File(tempFileName));
return tempFileName;
} catch (IOException ex) {
return null;
}
}
public static String createImageFromText(String text) {
String tempFileName = "text.png";
text = StringDivider(text);
String[] textParts = text.split("\n");
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
Font font = new Font("Arial", Font.PLAIN, 48);
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
int width = 0;
for (String textPart : textParts) {
int tempWidth = fm.stringWidth(textPart);
if (tempWidth > width) {
width = tempWidth;
}
}
width += 10;
int oneLineHeight = fm.getHeight();
int height = (oneLineHeight) * textParts.length;
g2d.dispose();
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2d.setFont(font);
fm = g2d.getFontMetrics();
g2d.setColor(Color.BLACK);
int index = 0;
for (String textPart : textParts) {
g2d.drawString(textPart, 5, (oneLineHeight) * index + fm.getAscent());
index++;
}
g2d.dispose();
try {
ImageIO.write(img, "PNG", new File(tempFileName));
} catch (IOException ex) {
return null;
}
return tempFileName;
}
public static void removeFile(String fileName) {
try {
File file = new File(fileName);
file.delete();
} catch (Exception ex) {
}
}
}

Source code for saving drawn view to image

I have aplication where I drawing object by canvas. And I want saving this pictures like image. For example bmp, or jpg to folder. How can I do it ? Here is bite of my code.
public class hell extends View{
public static int width= aktivita.width;
public static int koeficient = 5;
final Paint mPaint;
public static int t;
public boolean filter = true;
static ArrayList<Circle> mCircles;
private static boolean Kontroler = true;
public void draw(Canvas canvas) {
Paint p = new Paint();
p.setColor(Color.RED);
kres(canvas);
invalidate();
}
}
public krouzky(Context context, AttributeSet atrs) {
super(context, atrs);
mMalovani = new Paint();
mMalovani.setColor(Color.RED);
mMalovani.setAntiAlias(true);
createCircles();
}
Adding objects for draw
public static void Prid() {
int ran = aktivita.width/8;
mCircles.add(new Circle(80, 200, ran));
}
Make arrayList
private static void createCircles() { if (mCircles == null) { mCircles = new ArrayList<Circle>(); }
int r = aktivita.width/8;
mCircles.add(new Circle(80, 200, r));
}
Drawing object
private void kres(Canvas canvas) {
for (Circle c : mCircles) {
//
canvas.drawCircle(c.getCurrentX(), c.getCurrentY(), c.getRadius(),
mPaint);
}
}
I tried this, but after start with button click loadBitmapFromView(v);
save();
my program shut down, and in SD card is file with .png suffix. But It have 0 bites, and I´t open it.
public static Bitmap loadBitmapFromView(View view) {
// width measure spec
int widthSpec = View.MeasureSpec.makeMeasureSpec(
view.getMeasuredWidth(), View.MeasureSpec.AT_MOST);
// height measure spec
int heightSpec = View.MeasureSpec.makeMeasureSpec(
view.getMeasuredHeight(), View.MeasureSpec.AT_MOST);
// measure the view
view.measure(widthSpec, heightSpec);
// set the layout sizes
view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth() + view.getLeft(), view.getMeasuredHeight() + view.getTop());
// create the bitmap
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
// create a canvas used to get the view's image and draw it on the bitmap
Canvas c = new Canvas(bitmap);
// position the image inside the canvas
c.translate(-view.getScrollX(), -view.getScrollY());
// get the canvas
view.draw(c);
return bitmap;
}
public void save(){
String fileName = String.valueOf(Calendar.getInstance().getTimeInMillis());
// generate the image path
String imagePath = Environment.getExternalStorageDirectory().toString() + File.separator + fileName + ".png";
try {
// save the image as png
FileOutputStream out = new FileOutputStream(imagePath);
View view = null;
// compress the image to png and pass it to the output stream
loadBitmapFromView(view).compress(Bitmap.CompressFormat.PNG, 90, out);
// save the image
out.flush();
out.close();
} catch (Exception error) {
Log.e("Error saving image", error.getMessage());
}
}
To get a bitmap from a View:
public static Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return returnedBitmap;
}
To save it to SD Card:
public void saveImage(Bitmap b)
{
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
File file = new File(path, "XXXXXXXXXXX.jpg");
fOut = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
}
You can do just the insert in MediaStore, but it will loose quality. This way the compression is done with the quality you want.
EDIT:
Added some logging to help figure out why you're getting the FileNotFound exception:
public void saveImage(Bitmap b)
{
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
File file = new File(path, "XXXXXXXXXXX.jpg");
Log.d("saveImage", "File to save: " + file.getAbsolutePath());
try {
FileOutputStream fOut = new FileOutputStream(file);
}
catch(FileNotFoundException e) {
Log.d("saveImage", "Couldn't open file: " + e.getMessage());
}
if(fOut != null) {
b.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
}
}

Categories

Resources