Can't convert ByteArray from Camera2 to Base64 - java

I can't convert picture taken to readable base64, while starts the same as online converters, it's shorter and about half-way through becomes different.
Code
imageReader = ImageReader.newInstance(600,600, ImageFormat.JPEG, 1)
//Was switched to lambda
//imageReader.setOnImageAvailableListener(object: ImageReader.OnImageAvailableListener{
// override fun onImageAvailable(reader: ImageReader?) {
imageReader.setOnImageAvailableListener({ reader ->
val image = reader?.acquireLatestImage()
val buffer = image!!.planes[0].buffer
val bytes = ByteArray(buffer.remaining())
buffer.get(bytes)
var file = File(requireActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES),"img.jpeg")
var output = FileOutputStream(file)
output.write(bytes)
output.close()
image.close()
val encodedString: String = Base64.encodeToString(bytes, Base64.DEFAULT);
println(encodedString)
pictures.add(encodedString)
val sound = MediaActionSound()
sound.play(MediaActionSound.SHUTTER_CLICK)
}, handler)

Related

Zip byte[] in Kotlin. Java code to Kotlin

I'm trying to use this Java code but converting it to Kotlin in Android Studio, but I don't find a equivalent in kotlin for setSize(..) and .length in Kotlin. Could anyone help me?
public static byte[] zipBytes(String filename, byte[] input) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry(filename);
entry.setSize(input.length);
zos.putNextEntry(entry);
zos.write(input);
zos.closeEntry();
zos.close();
return baos.toByteArray();
}
Array in Kotlin has size field instead of Java array length and size field is Int in Kotlin, but ZipEntry.setSize(long size) accepts only long. So you can do something like this:
entry.setSize(input.size.toLong())
Or in more Kotlin idiomatic way:
entry.size = input.size.toLong()
when you write a byteArray in kotlin like this :
val byteArray = ByteArray(1024)
var length = byteArray.size
documentation says
An array of bytes. When targeting the JVM, instances of this class are represented as byte[].
#constructor Creates a new array of the specified [size], with all elements initialized to zero.
to prove it, checking the byte code created is this:
byte[] byteArray = new byte[1024];
int test = byteArray.length;
therefor in your case a can code like this.
entry.size = byteArray.size
but type of size is int and entry.size needs a long value, just add .toLong() to size for fixing this issue.
Try to use this code:
Import:
import java.io.IOException
import java.text.DecimalFormat
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
And you code in kotlin:
#Throws(IOException::class)
fun zipBytes(filename: String?, input: ByteArray): ByteArray? {
val baos = ByteArrayOutputStream()
val zos = ZipOutputStream(baos)
val entry = ZipEntry(filename)
entry.size = input.size.toLong()
zos.putNextEntry(entry)
zos.write(input)
zos.closeEntry()
zos.close()
return baos.toByteArray()
}

Base64.encodeToString() not working in Android

So i have a bitmap and now i want to convert it into an imageUri (or string),
i am using this code here but its just doesn't work instead of returning the imageUri its returning a long random text.
Here is my code :
ByteArrayOutputStream baos = new ByteArrayOutputStream();
saveBitmap.compress(Bitmap.CompressFormat.JPEG, 75, baos);
String path = Base64.encodeToString(baos.toByteArray(),Base64.DEFAULT);
And this is what i am getting :
Instead of Base64.DEFAULT, use Base64.NO_WRAP
String path = Base64.encodeToString(baos.toByteArray(),Base64.NO_WRAP);
try below way, should be work
byte[] data = convert image in byte.
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
byte[] data = Base64.decode(base64, Base64.DEFAULT);
String text = new String(data, "UTF-8");
Base64.encodeToString() encodes the byte array in a string. This isn't your uri. Rather this is your image/bitmap in Base64. You can use suitable Base64.decode to get back the byte array.
To get uri, you can use some of the other options including
Uri.fromFile(new File("your_file_path));
try {
val imageStream: InputStream? = requireActivity().getContentResolver().openInputStream(mProfileUri)
val selectedImage = BitmapFactory.decodeStream(imageStream)
val baos = ByteArrayOutputStream()
selectedImage.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val b = baos.toByteArray()
val encodedString: String = Base64.encodeToString(b,Base64.DEFAULT)
Log.d("check string" ,encodedString.toString())
} catch (e: IOException) {
e.printStackTrace()
}
For kotlin use this code and this is running successfully image to base64 when upload image to server . just put image uri "imageStream" here thats it.
Sorry guys, i thought Base64.encodeToString() will return me the imagePath, but i was wrong. Anyways i got the solution,
Here is the code that i have used,
ByteArrayOutputStream baos = new ByteArrayOutputStream();
saveBitmap.compress(Bitmap.CompressFormat.JPEG, 75, baos);
String path = MediaStore.Images.Media.insertImage(getContentResolver(),saveBitmap,"Title",null);

Difference in Base64 encoding

I am trying to encode, Image to Base 64 string in AngularJS2
handleFileSelect(evt) {
var files = evt.target.files;
var file = files[0];
if (files && file) {
var reader = new FileReader();
reader.onload = this._handleReaderLoaded.bind(this);
reader.readAsBinaryString(file);
}
}
_handleReaderLoaded(readerEvt) {
var binaryString = readerEvt.target.result;
this.model.UserProfileImageBase64 = btoa(binaryString);
console.log(this.model.UserProfileImage);
}
I am receiving a different string,in compare to encoding it from Java
Base64.encodeToString(getBytesFromBitmap(bitmap),Base64.NO_WRAP);
Any Idea how can we match both Base64 encoding? I had tried same with base64 encoding in angular as well
this.model.UserProfileImageBase64 = Base64.encode(binaryString);
But no dfiference in result.
BtoA and Base64 producing same result and, if I am verifying it online I am getting image as well but I need it in the same format which is generated by Java
I am getting the same result with java and javascript.
With java I did:
byte[] imageBytes = IOUtils.toByteArray(new URL("https://www.w3schools.com/css/paris.jpg"));
String base64 = Base64.getEncoder().encodeToString(imageBytes);
System.out.println(base64);
With javascript I did:
const fileReader: FileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onloadend = () => {
retVal.next(fileReader.result);
};
NOTE: I would suggest not to use readBynaryAsString as it is deprecated and might not work. FileReader
NOTE: That in javascript I wait till the file is uploaded to get the data and I passed to an observable next(...)
changeListener($event) : void {
this.readThis($event.target);
}
readThis(inputValue: any): void {
var file:File = inputValue.files[0];
var myReader:FileReader = new FileReader();
myReader.onloadend = (e) => {
this.image = myReader.result;
}
myReader.readAsDataURL(file);
}
component.html
<input type="file" accept="image/*" (change)="changeListener($event)">
Follow this link Angular 2 encode image to base64

Reading large number of bytes from GZIPInputStream

I am reading a gzipped file through GZIPInputStream. I want to read a large amount of data at once, but no matter how many bytes I ask the GZIPInputStream to read, it always reads far less number of bytes. For example,
val bArray = new Array[Byte](81920)
val fis = new FileInputStream(new File(inputFileName))
val gis = new GZIPInputStream(fis)
val bytesRead = gis.read(bArray)
The bytes read are always somewhere around 1800 bytes, while it should be nearly equal to the size of bArray, which is 81920 in this case. Why is it like this? Is there a way to solve this problem, and really have more number of bytes read?
I would try using akka-streams in case you have large amount of data.
implicit val system = ActorSystem()
implicit val ec = system.dispatcher
implicit val materializer = ActorMaterializer()
val fis = new FileInputStream(new File(""))
val gis = new GZIPInputStream(fis)
val bfs: BufferedSource = Source.fromInputStream(gis)
bfs exposes the Flow api for stream processing.
You can also get a stream from that:
val ss: Stream[String] = bfs.bufferedReader().lines()
The read might always return fewer bytes than you ask for, so in general you always have to loop, reading as many as you want.
In other words, giving GZIPInputStream a big buffer doesn't mean it will be filled on a given request.
import java.util.zip.GZIPInputStream
import java.io.FileInputStream
import java.io.File
import java.io.InputStream
import java.io.FilterInputStream
object Unzipped extends App {
val inputFileName = "/tmp/sss.gz"
val bArray = new Array[Byte](80 * 1024)
val fis = new FileInputStream(new File(inputFileName))
val stingy = new StingyInputStream(fis)
val gis = new GZIPInputStream(stingy, 80 * 1024)
val bytesRead = gis.read(bArray, 0, bArray.length)
println(bytesRead)
}
class StingyInputStream(is: InputStream) extends FilterInputStream(is) {
override def read(b: Array[Byte], off: Int, len: Int) = {
val n = len.min(1024)
super.read(b, off, n)
}
}
So instead, loop to drain instead of issuing one read:
import reflect.io.Streamable.Bytes
val sb = new Bytes {
override val length = 80 * 1024L
override val inputStream = gis
}
val res = sb.toByteArray()
println(res.length) // your explicit length
I'm not saying that's the API to use, it's just to demo. I'm too lazy to write a loop.
OK, I found the solution. There is a version of constructor for GZIPInputStream that also takes the size of the buffer.

convert dataURL to file using javascript

In one of my application i am cropping the image using http://fengyuanchen.github.io/cropper/
The resultant cropped image am getting in the base64 dataURL format, but i required that to be in file object format.
How to convert the dataURL to file either in client side or server side.
Use Blob instead of the deprecated BlobBuilder. The code is very clean and simple. (Manuel Di Iorio's code is deprecated.)
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
//test:
//var blob = dataURLtoBlob('data:text/plain;base64,YWFhYWFhYQ==');
Data URI scheme
How to convert dataURL to file object in javascript?
function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var bb = new BlobBuilder();
bb.append(ab);
return bb.getBlob(mimeString);
}
Then just append the blob to a new FormData object and post it to your server using ajax:
var blob = dataURItoBlob(someDataUrl);
var fd = new FormData(document.forms[0]);
var xhr = new XMLHttpRequest();
fd.append("myFile", blob);
xhr.open('POST', '/', true);
xhr.send(fd);
Thats my validation for input.
$data = $_POST['thumb'];
$uriPhp = 'data://' . substr($data, 5);
if ( base64_encode(base64_decode($uriPhp))){
$_POST['thumb'] = $uriPhp;
}
for saving I am using : http://www.verot.net/php_class_upload.htm
$foo = new Upload($_POST['thumb']);
if ($foo->uploaded) {
// save uploaded image with a new name
$foo->file_new_name_body = $name;
$foo->image_convert = 'png';
$foo->Process("uploads/");
}

Categories

Resources