Hi im decoding the base64 string data and saving into the database like url format with time stamp so i need to compress the decoded data and my compression like if the coming data is less than 100kb then no need to compress otherwise compress the data into 50% off.
try
{
String FileItemRefPath = propsFPCConfig.getProperty("fileCreationReferencePath");
String imageURLReferncePath = propsFPCConfig.getProperty("imageURLReferncePath");
File f = new File(FileItemRefPath+"/"+"productimages"+"/"+donorId);
String strException = "Actual File "+f.getName();
if(!f.exists())
{
if (!f.mkdirs())
{
System.out.println("direction creation failed");
return null;
}
}
else
{
boolean isdirCreationStatus = f.mkdirs();
}
String strDateTobeAppended = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
String fileName = strImageName+strDateTobeAppended;
savedFile = new File(f.getAbsolutePath()+"/"+fileName);
strException=strException+" savedFile "+savedFile.getName();
Base64 decoder = new Base64();
byte[] decodedBytes = decoder.decode(strImageBase64);
if( (decodedBytes != null) && (decodedBytes.length != 0) )
{
System.out.println("Decoded bytes length:"+decodedBytes.length);
fos = new FileOutputStream(savedFile);
System.out.println(new String(decodedBytes) + "\n") ;
int x=0;
{
fos.write(decodedBytes, 0, decodedBytes.length);
}
fos.flush();
}
if(fos != null)
{
fos.close();
System.out.println("file output stream"+savedFile.getName());
return savedFile.getName();
}
else
{
return null;
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if( fos!= null)
{
fos.close();
}
else
{
savedFile = null;
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
return savedFile.getName();
}
Your main problem is probably not going to be compressing it in Java. For that you can simply use something like the Deflater class. On iOS however it might be a little more complicated, as I'm not sure what kind of zlib-like tools you have available in iOS.
Related
I have a java program that is an extension to product. I wish to check if a file has changed and then copy it if it has.
I am using a ClassLoader to get the resource so I can get the last modified date. i:e
boolean copyFile = false;
String fileName = getRhumbaDirectory()+"\\stockexchanges.dict";
try {
File file = new File(fileName);
Long fileLastModified = file.lastModified();
URL url = this.getClass().getClassLoader().getResource("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");
Long resourceLastModified=0L;
if (url !=null) {
resourceLastModified = url.openConnection().getLastModified();
}
debugInst.debug("ExchangeList", "getData", MRBDebug.INFO, "Modified Date "+fileLastModified+" "+ resourceLastModified);
if (resourceLastModified > fileLastModified)
copyFile = true;
}
catch (IOException e){
copyFile = true;
}
if (copyFile) {
try {
InputStream input = this.getClass().getClassLoader().getResourceAsStream("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");
if (input == null) {
debugInst.debug("ExchangeList", "getData", MRBDebug.INFO, "Problem creating stockexchanges.dict file");
}
else {
FileOutputStream output = new FileOutputStream(fileName);
byte [] buffer = new byte[4096];
int bytesRead = input.read(buffer);
while (bytesRead != -1) {
output.write(buffer, 0, bytesRead);
bytesRead = input.read(buffer);
}
output.close();
input.close();
}
}
catch (IOException f) {
debugInst.debug("ExchangeList", "getData", MRBDebug.DETAILED, "Problem copying default file"+f.getMessage());
f.printStackTrace();
}
}
The code
URL url = this.getClass().getClassLoader().getResource("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");
Returns null whilst the code
InputStream input = this.getClass().getClassLoader().getResourceAsStream("com/moneydance/modules/features/securityquoteload/resources/stockexchanges.dict");
returns a valid stream. Shouldn't they both work?
Thanks to '#Stephen C' his suggestion found the reason. This forum will not be able to provide the work around as it is proprietary to the app.
I'm trying to compress the byte data from video, the app crashes when the file is over 10mb due to the limitations of Parse servers. So I'm trying to compress at 10mb. The code does well on older phones but on the newer phones the the video bytes easily go over 10mb but the code won't compress the bytes down to 10 mb. Is there something I can add or something?
private void uploadVideo() {
Intent videoIntent = new Intent (MediaStore.ACTION_VIDEO_CAPTURE);
mMediaUri = getOutputMediaFileUri (MEDIA_TYPE_VIDEO);
if (mMediaUri == null) {
// display an error
Toast.makeText (MemberActivity.this, R.string.error_external_storage,
Toast.LENGTH_LONG).show ();
} else {
videoIntent.putExtra (MediaStore.EXTRA_OUTPUT, mMediaUri);
videoIntent.putExtra (MediaStore.EXTRA_DURATION_LIMIT, 10);
videoIntent.putExtra (MediaStore.EXTRA_SIZE_LIMIT, 1024*1024*10);
videoIntent.putExtra (MediaStore.EXTRA_VIDEO_QUALITY, 0); // 0 = lowest res
startActivityForResult (videoIntent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
}
String mediaBytes = mMediaUri.getEncodedPath ();
//Set up video file and data
File iFile = new File (mediaBytes);
byte[] byteArray = new byte[(int) iFile.length ()];
try {
FileInputStream fileInputStream = new FileInputStream (iFile);
fileInputStream.read (byteArray);
for (byte aByteArray : byteArray) {
System.out.print ((char) aByteArray);
}
} catch (FileNotFoundException e) {
System.out.println ("File Not Found.");
e.printStackTrace ();
} catch (IOException e1) {
System.out.println ("Error Reading The File.");
e1.printStackTrace ();
}
final ParseFile file = new ParseFile ("HipkuVideo.mp4", byteArray);
file.saveInBackground (new SaveCallback () {
#Override
public void done(ParseException e) {
if (e == null) {
//addPhotoTransferToUserUpload (file);
// Show a simple toast message
Toast.makeText (MemberActivity.this, "Saving to SD Card",
Toast.LENGTH_SHORT).show ();
} else {
// Show a simple toast message
Toast.makeText (MemberActivity.this, "Error saving:" + e.getMessage (),
Toast.LENGTH_SHORT).show ();
}
and here is the compress code:
public static byte[] getByteArrayFromFile(Context context, Uri uri) {
byte[] fileBytes = null;
InputStream inStream = null;
ByteArrayOutputStream outStream = null;
if (uri.getScheme().equals("content")) {
try {
inStream = context.getContentResolver().openInputStream(uri);
outStream = new ByteArrayOutputStream();
// Compressor with highest level of compression
Deflater compressor = new Deflater();
compressor.setLevel(Deflater.BEST_COMPRESSION);
// Give the compressor the data to compress
compressor.setInput(fileBytes);
compressor.finish();
// Create an expandable byte array to hold the compressed data.
// It is not necessary that the compressed data will be smaller than
// the uncompressed data.
outStream = new ByteArrayOutputStream(fileBytes.length);
// Compress the data
byte[] buf = new byte[1024*1024*10];
while (!compressor.finished()) {
int count = compressor.deflate(buf);
outStream.write(buf, 0, count);
}
try {
outStream.close();
} catch (IOException e) {
}
// Get the compressed data
byte[] compressedData = outStream.toByteArray();
byte[] bytesFromFile = new byte[1024]; // buffer size (1 MB)
int bytesRead = inStream.read(compressedData);
while (bytesRead != -1) {
outStream.write(compressedData, 0, bytesRead);
bytesRead = inStream.read(compressedData);
}
fileBytes = outStream.toByteArray();
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
}
finally {
try {
inStream.close();
outStream.close();
}
catch (IOException e) { /*( Intentionally blank */ }
}
}
else {
try {
File file = new File(uri.getPath());
FileInputStream fileInput = new FileInputStream(file);
fileBytes = IOUtils.toByteArray(fileInput);
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
return fileBytes;
}
If you need to compress further than what's provided by ZLIB, take a look at Apache Commons Compress. Specifically, the section on XZ since that uses the LZMA compression algorithm which at it's highest level gives some of the best compression ratios around. Be sure to thoroughly test performance however since it can get a little slow. If you're worried about space you can cut out the Apache middleman and go straight to the Tukaani java library for the same.
Below is my code. I am converting images into bytearray values.
Here finalPathNames.size() == 4
So i want to save the byteArray values eachtime like byteArray1,byteArray2,byteArray3,byteArray4 which is inside for loop
Set<String> finalPathNames = sharedpre.getStringSet("prePathNames", null);
InputStream is = null;
for (String temp : finalPathNames) {
try {
is = new FileInputStream(temp);
try {
byteArray = streamToBytes(is);
} finally {
is.close();
}
} catch (Exception e) {
}
}
is there any optimized way to find result values
Send the bytes to the server, when you retrieve them or keep them in a list (in case you need them more than 1 time)
// as mentioned in the comments, user wants specifically 4 arrays
byte[][] byteArrays = byte[4][]; //
Set<String> finalPathNames = sharedpre.getStringSet("prePathNames", null);
InputStream is = null;
int index = 0;
for (String temp : finalPathNames) {
byteArrays[index] = new byte[0]; // in case of exception clear array. possibly set to null
try {
is = new FileInputStream(temp);
try {
byte[] byteArray = streamToBytes(is);
byteArrays[index] = byteArray;
} finally {
is.close();
}
} catch (Exception e) {
}
finally {
index++;
}
}
Then the resulting streams are available as:
byteArrays[0], byteArrays[1], byteArrays[2], byteArrays[3],
In my application I get a profile picture for user then I save it to a serialized class as string.
I do the GZIP compress and Base64 using the code below, but I can not do the reverse thing as you see in the getProfilePicture() method further down:
private void saveBitmap(){
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
String bitmapContent = "";
try {
bitmapContent = FileHelpers.compressAndBase64(byteArray);
//later save it...
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Error converting bitmap to gzip and base64");
}
}
public static String compressAndBase64(byte[] byteArray)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write(byteArray);
zos.close();
byte[] bytes = baos.toByteArray();
return Base64.encodeToString(bytes, Base64.DEFAULT);
}
Now I want to convert it back to Bitmap...but so far I didn't succeed to.
The steps are decoding back the string from Base64 to byte array then decompress the byte array and convert to Bitmap.
public Bitmap getProfilePicture(){
if(getProfilePhotoBase64() != null) {
byte[] decoded = Base64.decode(mProfilePhotoBase64.getBytes(), Base64.DEFAULT);
final int BUFFER_SIZE = 32;
ByteArrayInputStream is = new ByteArrayInputStream(decoded);
GZIPInputStream gis = null;
try {
gis = new GZIPInputStream(is, BUFFER_SIZE);
} catch (IOException e) {
e.printStackTrace();
}
StringBuilder string = new StringBuilder();
byte[] data = new byte[BUFFER_SIZE];
int bytesRead;
try {
while ((bytesRead = gis.read(data)) != -1) {
string.append(new String(data, 0, bytesRead));
}
} catch (IOException e) {
e.printStackTrace();
}
try {
gis.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
byte[] byteArray = string.toString().getBytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,byteArray.length);
if(bitmap != null) {
return bitmap;
} else {
return null;
}
}
return null;
}
This is the error message I get using the code above:
--- SkImageDecoder::Factory returned null
I can do this quite easy in PHP, but its darn hard to make it work in Java!
if(isset($_POST["photo"])) {
$photoContent = $_POST["photo"];
$photo = imap_base64 ($photoContent);
$photo = gzdecode($photo);
$filename = $_POST["username"].".png";
$dir = SITE_ROOT_PATH."/images/".$user."/".$filename;
file_force_contents($dir, $photo);
} else {
$filename = "NO_PROFILE_PHOTO";
}
Ok I managed to fix the problem in this way:
/**
* IMPORTANT NOTE!!!!!!!!!!!!!!
* String is first converted to byte array, then compressed using GZIP and then
* the resulting byte array is encoded to Base64.DEFAULT
* #return
*/
public String getProfilePhotoBase64() {
return mProfilePhotoBase64;
}
public Bitmap getProfilePicture(){
if(getProfilePhotoBase64() != null) {
byte[] decoded = Base64.decode(mProfilePhotoBase64.getBytes(), Base64.DEFAULT);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteArrayInputStream bis = new ByteArrayInputStream(decoded);
GZIPInputStream zis = null;
try {
zis = new GZIPInputStream(bis);
byte[] tmpBuffer = new byte[256];
int n;
while ((n = zis.read(tmpBuffer)) >= 0) {
bos.write(tmpBuffer, 0, n);
}
zis.close();
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeByteArray(bos.toByteArray(), 0
, bos.toByteArray().length);
if(bitmap != null) {
return bitmap;
} else {
return null;
}
}
return null;
}
And what is the problem exactly? compressAndBase64() will return an empty string as boas.toByteArray() will return 0 bytes as boas is just created and hence empty. You don't need to create a boas. Just change
return Base64.encodeToString(bytes, Base64.DEFAULT);
to
return Base64.encodeToString(byteArray, Base64.DEFAULT);
public class GenericWorldLoader implements WorldLoader {
#Override
public LoginResult checkLogin(PlayerDetails pd) {
Player player = null;
int code = 2;
File f = new File("data/savedGames/" + NameUtils.formatNameForProtocol(pd.getName()) + ".dat.gz");
if(f.exists()) {
try {
InputStream is = new GZIPInputStream(new FileInputStream(f));
String name = Streams.readRS2String(is);
String pass = Streams.readRS2String(is);
if(!name.equals(NameUtils.formatName(pd.getName()))) {
code = 3;
}
if(!pass.equals(pd.getPassword())) {
code = 3;
}
} catch(IOException ex) {
code = 11;
}
}
if(code == 2) {
player = new Player(pd);
}
return new LoginResult(code, player);
}
#Override
public boolean savePlayer(Player player) {
try {
OutputStream os = new GZIPOutputStream(new FileOutputStream("data/savedGames/" + NameUtils.formatNameForProtocol(player.getName()) + ".dat.gz"));
IoBuffer buf = IoBuffer.allocate(1024);
buf.setAutoExpand(true);
player.serialize(buf);
buf.flip();
byte[] data = new byte[buf.limit()];
buf.get(data);
os.write(data);
os.flush();
os.close();
return true;
} catch(IOException ex) {
return false;
}
}
#Override
public boolean loadPlayer(Player player) {
try {
File f = new File("data/savedGames/" + NameUtils.formatNameForProtocol(player.getName()) + ".dat.gz");
InputStream is = new GZIPInputStream(new FileInputStream(f));
IoBuffer buf = IoBuffer.allocate(1024);
buf.setAutoExpand(true);
while(true) {
byte[] temp = new byte[1024];
int read = is.read(temp, 0, temp.length);
if(read == -1) {
break;
} else {
buf.put(temp, 0, read);
}
}
buf.flip();
player.deserialize(buf);
return true;
} catch(IOException ex) {
return false;
}
}
}
Yeah so... My problem is that this seems to save 'something' in really complex and hard to read way(binary) and I'd rather have it as an .txt, in easily readable format. how to convert?
EDIT: I'm not using Apache Mina, so what should I replace
IoBuffer buf = IoBuffer.allocate(1024);
buf.setAutoExpand(true);"
with?
checkLogin() obviously checks whether the specified login has matching data present and whether the password is correct.
savePlayer() method saves the player.
loadPlayer() loads it again.
The data format used is gzip (wiki) and it is written as a stream of serialized data. If you want to make it more readable, you might want to overload (or just use it, if it is good) toString() method of Player class and to write player.toString() into a new text file using e.g. BufferedWriter wrapped around a File Writer:
String playerName = NameUtils.formatNameForProtocol(player.getName());
BufferedWriter writer = new BufferedWriter(new FileWriter(playerName + ".txt"));
writer.write(player.toString());
writer.close();