How to get size of image in android studio? - java

I am unable to get the size of the image. Below is my code.
File root = android.os.Environment.getExternalStorageDirectory();
File dirM = new File(root.getAbsolutePath()+"/Download/images.jpeg");
Long length = dirM.length();

You are actually fetching the length, not the size of the particular file. Use the below example to achieve what you want.
long imgSize = yourImageFileName.getAbsoluteFile().getTotalSpace();

Related

MimeBodyPart.getInputStream only returns the first 8192 bytes of an email attachment

I am using MimeBodyPart.getInputStream to retrieve a file attached to an incoming email. Anytime the attached file is larger than 8192 bytes (8 KiB), the rest of the data is lost. fileInput.readAllBytes().length seems to always be min(fileSize, 8192). My relevant code looks like this
val part = multiPart.getBodyPart(i).asInstanceOf[MimeBodyPart]
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition)) {
val filePath = fileManager.generateRandomUniqueFilename
val fileName = part.getFileName
val fileSize = part.getSize
val fileContentType = part.getContentType
val fileInput = part.getInputStream
doSomething(filePath, fileInput.readAllBytes(), fileName, fileSize, fileContentType)
}
Note that the variable fileSize contains the right value (e. g. 63209 for a roughly 64kb file). I've tried this with two different mail servers yielding the same result. In the documentation I cannot find anything about a 8KiB limit. What is happening here?
Note: When I use part.getRawInputStream I receive the full data!

How to extract a bitmap from a video?

I am working on a Java Application on Android Studio. I wanted any code where we can get Bitmap from video. I take video using absolute path. The input from video is 8 FPS.
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(absolutePath);
Just wanted to take Bitmap from video. Any help would be appreciated.
I tried the following code and it worked
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
//path of the video of which you want frames
retriever.setDataSource(absolutePath);
}catch (Exception e) {
}
String duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
int duration_millisec = Integer.parseInt(duration); //duration in millisec
int duration_second = duration_millisec / 1000; //millisec to sec.
int frames_per_second = 30; //no. of frames want to retrieve per second
int numeroFrameCaptured = frames_per_second * duration_second;
long frame_us=1000000/30;
capture=="+numeroFrameCaptured);
for (int i = 0; i < numeroFrameCaptured; i++)
{
//setting time position at which you want to retrieve frames
MEventsManager.getInstance().inject(MEventsManager.IMAGE,retriever.getFrameAtTime(frame_us*i,MediaMetadataRetriever.OPTION_CLOSEST));
}
retriever.release();
If you want image from video then you can use library called FFMPEG by implementing in gradle with this:
implementation 'com.arthenica:mobile-ffmpeg-min:4.3.1.LTS'
By using several commands you can convert all frames of video into image or you can get single frame also
for more information please visit:-
https://github.com/tanersener/mobile-ffmpeg
if you want only frame for displaying in imageview then you can use glide/picasso library.
Hope this will Help you..!!!

Keep dimension of new image when replacing old image using docx4j

I need to add an image to my docx file. The image is a png image of a signature that is to placed behind text in the signature line of a certificate to be downloaded by the user as a docx, a pdf or jpg. The first problem I encountered is that you can only add inline image using the latest version of docx4j (v6.1.2) and creating an image Anchor is currently disabled (see BinaryPartAbstractImage.java: line 1029). That's a problem since the signature image is not inline, it supposed to appear behind the name on the signature line. Instead of inserting one myself, my workaround is to place a placeholder image:
These images are mapped as image1.png and image2.png, respectively, on /word/media directory of the docx uncompressed version. The program then replaces these with the name, position, and actual png of the signature every time a certificate is generated.
The problem is that the images are scaled the same dimension as the placeholder image, where in fact it should look like this:
How can I get to keep the image dimension of the image after replacing, or at least the aspect ratio? Here is how I replace the placeholder image with the new image:
File approveBySignatureImage = new File(...);
final String approvedByImageNodeId = "rId5";
replaceImageById(approvedByImageNodeId,
"image1.png", approveBySignatureImage);
This is the actual method where the replacing happens:
public void replaceImageById(String id, String placeholderImageName, File newImage) throws Exception {
Relationship rel = document.getMainDocumentPart().getRelationshipsPart().getRelationshipByID(id);
BinaryPartAbstractImage imagePart;
if(FilenameUtils.getExtension(placeholderImageName).toLowerCase() == ContentTypes.EXTENSION_BMP) {
imagePart = new ImageBmpPart(new PartName("/word/media/" + placeholderImageName));
}
else if([ContentTypes.EXTENSION_JPG_1, ContentTypes.EXTENSION_JPG_2].contains(FilenameUtils.getExtension(placeholderImageName).toLowerCase())) {
imagePart = new ImageJpegPart(new PartName("/word/media/" + placeholderImageName));
}
else if(FilenameUtils.getExtension(placeholderImageName).toLowerCase() == ContentTypes.EXTENSION_PNG) {
imagePart = new ImagePngPart(new PartName("/word/media/" + placeholderImageName));
}
InputStream stream = new FileInputStream(newImage);
imagePart.setBinaryData(stream);
if(FilenameUtils.getExtension(newImage.getName()).toLowerCase() == ContentTypes.EXTENSION_BMP) {
imagePart.setContentType(new ContentType(ContentTypes.IMAGE_BMP));
}
else if([ContentTypes.EXTENSION_JPG_1, ContentTypes.EXTENSION_JPG_2].contains(FilenameUtils.getExtension(newImage.getName()).toLowerCase())) {
imagePart.setContentType(new ContentType(ContentTypes.IMAGE_JPEG));
}
else if(FilenameUtils.getExtension(newImage.getName()).toLowerCase() == ContentTypes.EXTENSION_PNG) {
imagePart.setContentType(new ContentType(ContentTypes.IMAGE_PNG));
}
imagePart.setRelationshipType(Namespaces.IMAGE);
final String embedId = rel.getId();
rel = document.getMainDocumentPart().addTargetPart(imagePart);
rel.setId(embedId);
}
You'll need to set the dimensions (or possibly just remove what you have?) on your placeholder image.
For help in doing that:-
docx4j inspects the image to work that out at https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/BinaryPartAbstractImage.java#L512 using org.apache.xmlgraphics ImageInfo.
See also CxCy:https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/BinaryPartAbstractImage.java#L1164
https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/BinaryPartAbstractImage.java#L815 shows scaling to maintain aspect ratio.

Setting the DPI meta-information for a jpeg file in Android

In an Android application that I am writing, I have a document image (jpeg) that is being uploaded to a server that recognizes the document and sends me back the relevant details. While all that is well and fine, the code in the server expects me to set the "Image DPI" meta-information as seen in mac like so,
The "Image DPI" that is shown in the above screenshot, isn't exactly its value. I have written a method that calculates the dpi-value. How do I set the thusly calculated dpi-value to the meta-information of my jpeg document? I have been able to set this particular meta-information in the application's iOS counterpart, but in Android, two days of relentless trying has left my errand futile.
I do know about ExifInterface, and I have been unlucky in using its setAttribute(String key,String value) method. (What should be the key? What should be the value? How do I set the unit? SHOULD I set the unit?).
I have also seen Java-related solutions to this that suggest the use of javax.imageio.*package which is simply unavailable for Android.
Has anyone faced issues like this? How do I go on about this issue?
To edit the value, you need to first create a byte[] array that will store the Bitmap.compress(). Here is a part of my code where I do just that(input being the source Bitmap).
ByteArrayOutputStream uploadImageByteArray = new ByteArrayOutputStream();
input.compress(Bitmap.CompressFormat.JPEG, 100, uploadImageByteArray);
byte[] uploadImageData = uploadImageByteArray.toByteArray();
Based on the JFIF structure, you need to edit the 13th, 14th, 15th, 16th, and 17th indexes in the byte array. 13th specifying the density type, 14th and 15th the X resolution, and 16th and 17th holding the Y resolution. I got the dpi using the following method:
private long getDPIinFloat(int width, int height) {
return (long) Math.sqrt(width * width + height * height) / 4;
}
After I got the DPI, I had to do some bit manipulation like so:
long firstPart = dpiInFloat >> 8;
if (GlobalState.debugModeOn) {
Log.d(TAG, "First Part: " + firstPart);
}
long lastPart = dpiInFloat & 0xff;
if (GlobalState.debugModeOn) {
Log.d(TAG, "Last Part: " + lastPart);
}
And then, manipulate the byte information like so:
uploadImageData[13] = 1;
uploadImageData[14] = (byte) firstPart;
uploadImageData[15] = (byte) lastPart;
uploadImageData[16] = (byte) firstPart;
uploadImageData[17] = (byte) lastPart;
//Upload Image data to the server
This way, I was able to set the dpi information on the metadata.

ImageView doesn't display JPEG

I have an ImageView that is not wanting to display a JPEG, but will display all the other PNG's in the ListView. I have tried things such as adding a transparent background, and nothing works. To get the data, I downloaded all of the images, and stored them into a blob in a SQLite database. I retrieved them by fetching the info from the database, and according to the database, their is binary JPEG data available.
Here is the image I am trying to display (I have it already downloaded in binary data): http://image-store.slidesharecdn.com/1a4f1444-02e2-11e4-9166-22000a901256-large.jpeg
Here is the code I am using to try and convert the binary data back to a Bitmap:
try
{
String profilePictureBytes = submittedImageTemp; // this string holds the binary jpeg, png data, etc.
byte[] encoded;
try
{
encoded = profilePictureBytes.getBytes("ISO-8859-1");
ByteArrayInputStream imageStream = new ByteArrayInputStream(encoded);
Bitmap theBitmap = BitmapFactory.decodeStream(imageStream);
attachPreviewOne.setBackgroundColor(Color.TRANSPARENT);
attachPreviewOne.setImageBitmap(theBitmap);
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
A. Extract your jpeg from the blob to a temp file. You might want to use the getCacheDir() folder for that
B. Load it from temp file:
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(jpegTemFile, options); //<------------
imageView.setImageBitmap(bm);
The above should work fine. Still - few things you might want to consider:
C. Depending on your jpeg, the loading operation - decodeFile - might be lengthy. You might want to do it in an
AsyncTask.
D. You might also want to consider setting a sampleSize so to reduce size of loaded image:
options.inSampleSize = 2; // setting to N will reduce in-memory size by factor of N*N
Or, you might use Picasso for the job. I used it in several projects and was happy with what I got:
Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)

Categories

Resources