Difference in Base64 encoding - java

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

Related

File upload with Jersey, File not being decoded

I've been trying to do file upload to a server from Javascript to a Jakarta REST service. The file is not getting decoded and I can't find what's wrong.
The upload code I'm using in javascript is basic FormData upload (vanillajs):
var url=.....
var xhttp = new XMLHttpRequest();
var formData = new FormData();
xhttp.onreadystatechange = () => {
if (this.readyState == 4)
{
if (this.status == 200)
{
if (successCallback != null) successCallback(this.responseText);
}
else
{
if (errorCallback != null) errorCallback(this.status, this.statusText);
}
}
};
xhttp.open("POST", url, true);
formData.append("file", file);
xhttp.send(formData);
The way I'm getting the file is to use a file input, and when the user loads an image, I load a picture of it and use that (React):
const [imgSrc, setImgSrc] = React.useState('');
const loadImage=(e)=>{
var file=e.target.files[0];
var reader = new FileReader();
reader.onload = (e2)=>{
setImgSrc(e2.target.result);
}
reader.readAsDataURL(file);
}
<input type="file" accept="image/*" onChange={(e)=>loadImage(e)} />
That seems to work fine. When I look at the request headers I see:
Content-Type: multipart/form-data; boundary=....
and the payload starts with:
file: data:image/jpeg;base64,/9j/...
Then the REST service I'm using to receive this is:
#POST
#Path("/submit")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadImage(
#FormDataParam("file") File fileBody,
#FormDataParam("file") FormDataContentDisposition metadata)
{
// set up S3 bucket, all that works fine
s3.putObject("mybucket", "pick_a_name", new FileInputStream(fileBody), null);
}
and that works, BUT, the file content is the literal content of the payload:
data:image/jpeg;base64,/9j/...
So it's not being recognized as a base 64 encoded file content and being decoded.
I've gone through various iterations and questions, including variations that result in 400 or 415 errors, but as far as I can tell these things look like they should line up.
A few more data points:
Tomcat 10
Jakarta 3.0.0
Jersey 3.0.3 (and jersey media multipart 3.0.3)
Java 8
Any suggestions would be appreciated. Thanks!
I'd like to get a "real" (what's the correct problem and solution) answer, but in the meantime I went with a hack:
InputStream outStream = hackBase64Decode(fileBody);
s3.putObject("mybucket", "pick_a_name", outStream, null);
private InputStream hackBase64Decode(File fileBody) throws Exception
{
FileInputStream fs = new FileInputStream(fileBody);
int ch;
do {
ch = fs.read();
} while (ch != ',');
return Base64.getDecoder().wrap(fs);
}
The best that can be said for that is it works. Again, though, would prefer a real answer.

AWS lambda (server less) file upload using java

I'm trying to upload file to AWS S3 bucket using Lambda server less application written in Java.
I'm hitting the endpoint with file using postman option binary (screenshot attached).
And I'm receiving binary content as string in my endpoint like as follows (screenshot attached).
I'm trying to convert this binary string to byte array and upload to S3 bucket.
I'm getting success response, But when i downloads the file / image it's looks like not an actual file.
Sample code:
#Override
public ServerlessOutput handleRequest(ServerlessInput serverlessInput, Context context) {
ServerlessOutput output = new ServerlessOutput();
String keyName = UUID.randomUUID().toString();
String content = serverlessInput.getBody();
byte[] encoded = this.toBinary(content).getBytes();
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(encoded.length);
metadata.setContentType(PNG_MIME);
s3.putObject(new PutObjectRequest(
ARTICLE_BUCKET_NAME,
keyName,
new ByteArrayInputStream(encoded),
metadata)
);
output.setBody("Successfully inserted article ");
}
private String toBinary(String data) {
byte[] bytes = data.getBytes();
StringBuilder binary = new StringBuilder();
for (byte b : bytes) {
int val = b;
for (int i = 0; i < 8; i++) {
binary.append((val & 128) == 0 ? 0 : 1);
val <<= 1;
}
binary.append(' ');
}
return binary.toString();
}

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/");
}

Invalid value for ByteString for Update photo in Google Apps engine in java

I am trying to update photo using Google apps engine.I have imageurl i convert it into byte array and then encode
it using base64.i got encoded string,now i m trying to update photodata using directory API Reference
https://developers.google.com/admin-sdk/directory/v1/reference/users/photos#resource
after update i got error invalid byteString.I face this problem from yesterday.So Let me know where i did wrong? Below is my code.
import com.google.appengine.repackaged.org.apache.commons.codec.binary.Base64;
above class used for Base64.
URL url = new URL(myImageUrl);
ByteArrayOutputStream bais = new ByteArrayOutputStream();
InputStream is = null;
try {
is = url.openStream ();
byte[] byteChunk = new byte[4096]; // Or whatever size you want to read in at a time.
int n;
while ( (n = is.read(byteChunk)) > 0 ) {
bais.write(byteChunk, 0, n);
}
System.out.println(byteChunk);
byte[] encoded = Base64.encodeBase64(byteChunk);
String ecodedString = new String(encoded, "UTF-8");
ecodedString = ecodedString.replace("/", "_");
ecodedString = ecodedString.replace("+", "-");
ecodedString = ecodedString.replace("=", "*");
System.out.println(ecodedString);
Padding could be the problem, try not replacing "=" with "*". See also:
Converting string to web-safe Base64 format
p.s. repackaged libs are discouraged in app engine; you may use DatatypeConverter.printBase64Binary() instead.

How to send binary data from AS3 through Java to a filesystem?

I've got XML data in AS3 that needs to be compressed, validated on my Java Google App Engine servlet then saved to a file in Google Cloud Storage. Later that file will be opened and decompressed by the AS3 client. The process works if I do it with plain XML or text, but if I ByteArray#compress the data, it dies during ByteArray#uncompress with "There was an error decompressing the data".
I've tried setting the content type and mime type at various points, as well as encoding with Base64, but every attempt seems to break in a different way and I never get the same XML back that I sent in. Do I need to use multipart? Should I compress on the server? What's the best practice for doing this?
Sending the data from AS3:
// compress xml using zlib
var xml:XML = <contents><thing>value</thing></contents>;
var bytes:ByteArray = new ByteArray();
bytes.writeObject(xml);
bytes.position = 0;
bytes.compress();
var request:URLRequest = new URLRequest(url);
var urlVariables :URLVariables = new URLVariables();
urlVariables.filename = "somefile.bin";
urlVariables.contents = bytes;
request.data = urlVariables;
request.method = URLRequestMethod.POST;
loader = new URLLoader();
loader.load(request);
Receiving it in the Java servlet and creating the file:
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String filename = req.getParameter("filename");
byte[] contents = req.getParameter("contents").getBytes();
GSFileOptionsBuilder optionsBuilder = new GSFileOptionsBuilder()
.setBucket("bucketname")
.setKey(filename)
.setAcl("public-read")
.setMimeType("binary/octet-stream");
AppEngineFile writableFile = fileService.createNewGSFile(optionsBuilder.build());
boolean lockForWrite = true;
FileWriteChannel writeChannel = fileService.openWriteChannel(writableFile, lockForWrite);
writeChannel.write(ByteBuffer.wrap(contents));
writeChannel.closeFinally();
}
Opening the new file in AS3:
var url :String = "http://commondatastorage.googleapis.com/bucketname/somefile.bin";
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.GET;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, handleComplete);
loader.load(request);
protected function handleComplete (event:Event):void {
var bytes:ByteArray = new ByteArray();
bytes.writeObject(event.target.data);
// dies on this line with "There was an error decompressing the data."
bytes.uncompress();
var xml:XML = new XML(new String(bytes));
trace(xml);
}
Here is the code that I use to save an xml. I send the data to PHP but I would think it would work the same way for you... I haven't had any trouble with it.
var createXMLURL:URLRequest = new URLRequest("createXML.php");
createXMLURL.method = URLRequestMethod.POST;
var Variables:URLVariables = new URLVariables();
Variables.xmlString = xml.toXMLString();
Variables.filename = filename;
createXMLURL.data = Variables;
var loader:URLLoader = new URLLoader();
loader.dataFormat = "VARIABLES";
loader.addEventListener(Event.COMPLETE, xmlCreated);
loader.load(createXMLURL);
Let me know if you have any questions about what some of the variables are since I did not include their declarations (I think they are pretty easy to figure out).
Now this doesn't send that data in binary format like you were asking for, but I don't know why you wouldn't be able to convert the string to binary once you receive it in java if you really need the raw bytes.
I would base64 encode before you POST if from the client, store it that way in a TextProerty, then base64 decode / decompress when received back at the client. If you want to store it as binary on GAE, then base64 decode it into a Blob. Here are some code snippets I pieced together using your code, and something similar I do using HttpService -- apologies in advance for not extensively proofing it. HTH.
private var _serviceHttp:HTTPService = new HTTPService;
private function postBytes():void {
var xml:XML = <contents><thing>value</thing></contents>;
var bytes:ByteArray = new ByteArray();
bytes.writeObject(xml);
bytes.position = 0;
bytes.compress();
var enc:Base64Encoder = new Base64Encoder();
enc.encodeBytes(bytes, 0, bytes.length);
var myObj:Object = new Object();
myObj["bytes"] = enc.toString();
// myObj["other_variables"] = your_other_varaibles;
_serviceHttp.method = "POST";
_serviceHttp.resultFormat = "flashvars";
_serviceHttp.url = your_url_here;
_serviceHttp.addEventListener(ResultEvent.RESULT, urlHandler);
_serviceHttp.addEventListener(FaultEvent.FAULT, urlErrorHandler);
_serviceHttp.send(myObj);
}

Categories

Resources