This question is related to my previous question but you dont need to read that in order to understand it.
Now I was trying to convert bitmap into smaller parts and then save those smaller parts.
Issue I get is, Only the first part gets saved in the file whose size is way bigger than the full image. Below is the code I am using:
for (int i = 0; i < Image.getHeight(); i++)
{
fout = new FileOutputStream(file, true);
Bitmap temp = Bitmap.createBitmap(Image, 0, i,Image.getWidth(), 1);
temp.compress(Bitmap.CompressFormat.PNG, 100, fout);
fout.flush();
fout.close();
}
The Code is pretty simple but i dont understand that why the only first row gets written in the file.
UPDATE::
Merlin and Deepak are right. I tried now with giving different names and all the parts were successfully written to different files. Now you know the problem, should i go for the removing of header from second chunk and removing of eof from first chunk or what?
I'm going to resist the urge to ask why on earth you are doing this as it is highly inefficient, so let's have a look.
So you are writing one line of pixels at a time but you are writing them to the same file repeatedly with the append flag set to true which is correct.
What you have missed is the fact that when you write a bitmap you are writing is self contained. So a program reading th first line will expect that to be the entire bitmap.
This is the equivalent of having an EOF marker in a text file. All the lines are being written but when reading it the reader gives up after the first EOF
You would need to research the the structure of a PNG file to understand more fully what is happening
Since you are appending compressed files (.png) one after the other, opening the resultant file will just show the first bit encoded data, which is your first row. This is logical too since the encoded image header has number of bytes comprising the encoded content and the decoders will not bother about the rest of the data in the file after end marker.
I just tried copying an .png file at the end of another, when i open the file i seen the unchanged first image!
Your logic is wrong because you cannot append each row as png to a file. Probably it has some header stuff, so they would be appended after each append.
Related
I am working on an Android app like Notepad.
There are two sections.
Text Only
Text with images
A notepad which can only get text from user and save it in db and then retrieve is done.
The another section, will work basically like MS Word.
User can select image from gallery and save it in notepad.
But how can I achieve it? Because I want to store that whole data (image & text) into db as it is. Means suppose user added an image after 2 lines of text. Then app should retrieve it from db in that format only.
Any suggestions? Please help me. Thanks in advance.
The most simple solution would be to define tags or some other form of markup language, that would store that image within a text as a path to file on Disk for example which is imho better alternative than storing it in SQLite but if you insist on database, you can store something like an imageId and keep it the there... However, you are manually doing something, that has already been optimized for you when trying to handle the byte array instead of a file in memory ..
Once you store images in this custom markup language, you can parse it and split the text on chunks between the images which you populate dynamically to some ViewGroup(i.e. LinearLayout) as separate TextViews and ImageViews...
Finally, if you want a solution quickly, you can use some already developed libraries such as this : https://android-arsenal.com/details/1/1696 ... However, this pattern is so common that you can find a great number of libraries that do exactly the thing you are looking for ...
Don't reinvent the wheel if it's not necessary..
You can save the byteArray or uri of images in the database.
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray();
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
Uri uri = Uri.parse(path);
Hope this helps ....
In my app, I receive some files. At the beginning I just have the size of this file. So I create an empty file (filled of 0). After creating this file, I will receive 1024 bytes per seconds. Thoses bytes chunks correspond to file parts.
So I need to replace the current content of the file by the bytes I'm receiving.
This means I have to read/write the file every seconds. For small files, it's not a problem, but sometimes I'm having big files (>2Mo).
I searched but I couldn't find a way to replace a part of file at a given index without reading and reaching the while file everytime. Is there any simple solution and performance friendly?
After trying so much things with OuputStream, FileChannel, etc... and post this question. I finally found the "RandomAccessFile" class that solves my problem.
https://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html
Business Purpose :
1) Want to add large string(data) of length 1200 to the .jpg / .mp4 file in android mobile
2) Later the file can be uploaded to server from mobile
3) In server we retrieve the added data from the file
What i have tried in .jpg file :
Used the below code for adding data
ExifInterface exif = new ExifInterface(photoPath);
exif.setAttribute("UserComment", "String having length of 1000");
exif.saveAttributes();
This code is working. After i set the attribute, i can able to read it by
String userComment=exif.getAttribute("UserComment");
In low end mobile it showed error "stack corruption detected: aborted" while saving attribute.Later i found it taken up to 663 characters alone.
In high end mobile the string of length saved up to 1999 after saveAttribute().
Is there any other way to add some tag/meta data/string to .jpg,.mp4 and .mp3 file ?
So that the added data can be retrieved later.
please share your views. Is it possible ?
It sounds as if it's certainly is possible using your approach, but you're running into various implementation limits in how long attribute values are supported.
One solution to at least investigate is of course to split your 1200-byte string into multiple shorter strings, say four 300-byte ones, and add those as UserComment0, UserComment1 and so on. That should be trivial to extract and concatenate to get back your original longer string, and might work around the limitations.
Praveen,
take a look at Steganography project
https://github.com/johnkil/Steganography
Thanks,
Jey.
In my Android project, I have a 2M-bytes raw data file. Since my application is a long-life app, I don't want it to always seize 2M memory. The data file has been formatted, once I need to some data from the data file, I just need to seek to some position and read several bytes.
The Resource class can only return an InputStream on raw file, but InputStream cannot do random read.
Is there a way on Android to random read some bytes from the raw data file? Or I have to read the entire file into memory when I only need a few bytes.
InputStream can skip bytes with skip() can also mark an offset with mark(), on reset() it can go back to marked position. All that can be used to do random IO.
You can store byte offsets in a separate lookup file as well.
Android is built upon Java so take a look at this tutorial:
http://docs.oracle.com/javase/tutorial/essential/io/rafs.html
Suppose an app gets a content stream by being called with the android.intent.action.SEND filter. Also suppose the Uri and the stream is received like this:
Uri contentUri = (Uri) extras.get(Intent.EXTRA_STREAM);
InputStream in = getContentResolver().openInputStream(contentUri);
Now, how can I determine the total length of the content without reading the whole stream? Is it even possible? in.available() isn't necessarily accurate, so I guess I do have to read the stream until the end, first?
The content might be very large, like about 50MB or more. So, I'd rather only read it once.
You can't determine the amount of data in a stream without reading it; you can, however pass the length via some other extra if you are the source of input.
I would read into a ByteArrayOutputStream and then call toByteArray() to get the resultant byte array. You don't need to define the size in advance (although it's possibly an optimisation if you know it. In many cases you won't)