Decode Image data in Android - javascript

I am confusing to decode image data in Android.
Following code is ont working. It got "bad base-64" error message.
String c = data.getString("profile_picture").replace("\n", "");
byte [] picture_data = Base64.decode(c, Base64.DEFAULT); // ******** ERROR (bad base-64) *******
InputStream is = new ByteArrayInputStream(picture_data);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeStream(is, null, options);
ImageView _profile_image = (ImageView)view.findViewById(R.id.image_view);
_profile_image.setImageBitmap(bmp);
I tried all Base64.* as a decode parameter.
I have working code in Swift and Javascript with same image data(json string).
Swift
let _profileImageView = UIImageView()
let _profile_image: UIImage? =
registration_data["profile_picture"].string!.urlDecode()
_profileImageView.image = _clinic_image
_profileImageView.frame = CGRect(x: 10,
y: 10,
width: _cellDetailView.frame.width * 0.2,
height: _cellDetailView.frame.width * 0.2
)
_cellDetailView.addSubview(_profileImageView)
public func urlDecode() -> UIImage? {
var img: UIImage = UIImage()
let base64String = self.replacingOccurrences(of: "}", with: "+")
let decodeBase64:NSData? =
NSData(base64Encoded:base64String, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)
if let decodeSuccess = decodeBase64 {
img = UIImage(data: decodeSuccess as Data)!
}
return img
}
Javascript
document.getElementById('profile_photo_preview').src = "data:image/jpg;base64," + decodeURI(encodeURI(jsondata.profile_picture))
What I want to do is to make the java code as same as in swift and in javascript.
I know in swift, if I remove NSData.Base64DecodingOptions.ignoreUnknownCharacters option, it didn't show image.
How can I do this?
Please give me an advice.

Try to use encoding with
java.io.ByteArrayOutputStream boas = new java.io.ByteArrayOutputStream();
Bitmap bm = ((android.graphics.drawable.BitmapDrawable) imageview1.getDrawable()).getBitmap();
bm.compress(Bitmap.CompressFormat.JPEG, 100, boas);
byte[] imageBytes = boas.toByteArray();
String img_str = Base64.encodeToString(imageBytes, Base64.DEFAULT);
And decoding with
byte[] decoded1String = Base64.decode(img_str, Base64.DEFAULT); Bitmap decoded1Byte = BitmapFactory.decodeByteArray(decoded1String, 0, decoded1String.length);
imageview1.setImageBitmap(decoded1Byte);

Related

Javascript CryptoJS v3.1.2 AES.encrypt and C# AesManaged output are not same for the same input

I am trying to replicate Javascript CryptoJS v3.1.2 AES.encrypt in C#. I have tried AesManaged, RijndaelManaged but not able to replicate same output in C# as javascript produces.
The java script code is as below:
var enteredText = "123456";
var _0x6722=["\x75\x37\x47\x75\x35\x70\x6F\x73\x76\x77\x44\x73\x58\x55\x6E\x56\x35\x5A\x61\x71\x34\x67\x3D\x3D","\x70\x61\x72\x73\x65","\x42\x61\x73\x65\x36\x34","\x65\x6E\x63"];
var rkEncryptionKey=CryptoJS[_0x6722[3]][_0x6722[2]][_0x6722[1]](_0x6722[0])
var _0x283e=["\x35\x44\x39\x72\x39\x5A\x56\x7A\x45\x59\x59\x67\x68\x61\x39\x33\x30\x61\x55\x4B\x32\x77\x3D\x3D","\x70\x61\x72\x73\x65","\x42\x61\x73\x65\x36\x34","\x65\x6E\x63"];
var rkEncryptionIv=CryptoJS[_0x283e[3]][_0x283e[2]][_0x283e[1]](_0x283e[0])
var utf8Stringified = CryptoJS.enc.Utf8.parse(enteredText);
var encrypted = CryptoJS.AES.encrypt(utf8Stringified.toString(), rkEncryptionKey,
{
mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, iv: rkEncryptionIv
});
var encryptedText = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
This will produce jvYWNkANUAkYOSEbuJxv1w== as output in javascript.
Below is my C# code which I have written for the AES:
string result = "";
try
{
byte[] keybyte = Convert.FromBase64String("u7Gu5posvwDsXUnV5Zaq4g==");
byte[] keyiv = Convert.FromBase64String("5D9r9ZVzEYYgha930aUK2w==");
byte[] bytes = Encoding.UTF8.GetBytes("123456");
AesManaged aesManaged = new AesManaged();
aesManaged.KeySize = 128;
aesManaged.Key = keybyte;
aesManaged.BlockSize = 128;
aesManaged.Mode = CipherMode.ECB;
aesManaged.Padding = PaddingMode.PKCS7;
aesManaged.IV = keyiv;
AesManaged aesManaged2 = aesManaged;
string text;
using (ICryptoTransform cryptoTransform = aesManaged.CreateEncryptor(aesManaged.Key, aesManaged.IV))
{
text = Convert.ToBase64String(cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length));
}
result = text;
}
catch { }
My C# code is not producing the same output. Please suggest what issue I have in my C#

how to show image from server in javascript?

I am making Thumbnail View pages.
I stored thumbnail images external folder(C:/temp/image) and I get them from server as byte data.
now I want to convert this data into image in javascript and show in HTML.
so I tried to make blob URL using these byte data. But I got error "FILE NOT FOUND"
Here is my code. Please let me know what i'm missing
(It is Spring boot and angular.js )
Service
public List<Map<String, Object>> listRecentWithInfo( int userid) throws IOException, SerialException, SQLException {
List<Map<String, Object>> recentList = dashboardDao.listRecentWithInfo( userid);
for (Map<String, Object> map : recentList) {
int dashboardid = (int) map.get( "DASHBOARDID");
FileInputStream is = null;
BufferedImage bi = null;
ByteArrayOutputStream bao= null;
byte[] imageByte = null;
ResponseEntity<byte[]> res = null;
HttpHeaders headers = new HttpHeaders();
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
if (thumbnailDao.findOne( dashboardid) != null) {
String path = thumbnailPath + thumbnailDao.getOne( dashboardid).getFileName();
is = new FileInputStream(path);
bi = ImageIO.read(is);
System.out.println(bi.getType());
bao = new ByteArrayOutputStream();
ImageIO.write(bi, "png", bao);
imageByte = bao.toByteArray();
res = new ResponseEntity<>(imageByte, headers, HttpStatus.OK);
}
map.put("THUMBNAIL", res);
}
return recentList;
}
js
$http.get("app/dashboard/recentWithInfo").then( function( rtn) {
rtn.data.map(item=> {
if (item.THUMBNAIL) {
var bytes = new Uint8Array(item.THUMBNAIL.body / 2);
for (var i = 0; i < item.THUMBNAIL.body; i += 2) {
bytes[i / 2] = parseInt(item.THUMBNAIL.body.substring(i, i + 2), /* base = */ 16);
}
// Make a Blob from the bytes
var blob = new Blob([bytes], {type: 'image/png'});
var imageUrl = URL.createObjectURL(blob);
URL.revokeObjectURL(imageUrl);
item.THUMBNAIL = imageUrl;
}
});
$scope.items = rtn.data;
console.log(rtn.data);
});
});
Thanks in advance!
I Got a solution By myself
I realized that I can convert Byte Data into Base64 just like that
"data:image/png;base64," + item.THUMBNAIL.body;
and this BASE64 encoded data can be used as Image source in HTML!

C# Bitmap to Html img using ajax doesn't work

This is my C# code to make Bitmap
public void VerificationCode(int captchaWidth = 75, int captchaHeight = 25)
{
var colorList = new List<Color> { Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Blue, Color.Brown };
Response.ContentType = "image/gif";
Response.Clear();
Response.BufferOutput = true;
var randString = new Random((int)DateTime.Now.Ticks).Next(99999).ToString("00000");
Session["VerificationCode"] = randString;
var bitmap = new Bitmap(captchaWidth, captchaHeight);
var graph = Graphics.FromImage(bitmap);
var font = new Font("Arial", 16, FontStyle.Italic);
var fontColor = Color.FromArgb(153, 153, 153);
graph.Clear(Color.White);
graph.DrawString(randString, font, new SolidBrush(fontColor), 0, 0);
var random = new Random((int)DateTime.Now.Ticks);
var randomColor = new Random((int)DateTime.Now.Ticks);
for (var i = 0; i < 100; i++)
{
var c = randomColor.Next(0, colorList.Count);
var randPixelX = random.Next(0, captchaWidth);
var randPixelY = random.Next(0, captchaHeight);
bitmap.SetPixel(randPixelX, randPixelY, colorList[c]);
}
bitmap.Save(Response.OutputStream, ImageFormat.Gif);
}
$('#ChangeCaptcha').on('click', function () {
$.ajax({
url: '#Url.Action("VerificationCode", "Base")',
type: 'Get',
async: false,
success: function (data) {
console.log(data);
$('#CaptchaImage').attr('src', "data:image/gif;base64," + data);
}
});
});
This is my Javascript code using ajax to get Bitmap to change img src.
But It's doesn't work.I alway get error message. Could any one can help me to fix this issue. I have used change minitype to "data:image/bmp;base64" or "data:image/gif," then I always get error.
You are serializing Bitmap to response stream. Your JS will receive a .net serialized object of type System.Byte[] and not a Base64 encoded string.
Save your bitmap to byte array through MemoryStream.ToArray()
Convert this array to Base64 string with Convert.ToBase64String(bitmapBytes)
Send resulting string to JS

Convert C# encryption mechanism code to javascript

I have code to encrypt and decrypt the files in C#. Now I need to move the encryption task to front end an I need to write javascript code to encrypt the .xlsx files. Below is the C# code for encrypt and decrypt:
private void EncryptFile(string inputFile, string outputFile)
{
try
{
string password = #"myKey123"; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
string cryptFile = outputFile;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
cs.WriteByte((byte)data);
fsIn.Close();
cs.Close();
fsCrypt.Close();
}
catch(Exception ex)
{
// MessageBox.Show("Encryption failed!", "Error");
}
}
private void DecryptFile(string inputFile, string outputFile)
{
{
string password = #"myKey123"; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateDecryptor(key, key),
CryptoStreamMode.Read);
FileStream fsOut = new FileStream(outputFile, FileMode.Create);
int data;
while ((data = cs.ReadByte()) != -1)
fsOut.WriteByte((byte)data);
fsOut.Close();
cs.Close();
fsCrypt.Close();
}
}
I tried to create a encryption in javascript as below:
var reader = new FileReader();
reader.onload = function (e) {
var encrypted = CryptoJS.AES.encrypt(e.target.result, 'myKey123');
var data = new FormData();
var encryptedFile = new File([encrypted], file.name, { type: "text/plain", lastModified: new Date() });
data.append('file', encryptedFile);
$.ajax({
url: 'http://localhost:57691/api/WithKey/UploadFile',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (data) {
debugger;
}
});
};
reader.readAsDataURL(file);
I also tried converting key to utf16 as below:
function wordsToBytes (words) {
for (var bytes = [], b = 0; b < words.length * 32; b += 8)
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
return bytes;
}
var temp = CryptoJS.enc.Utf16.parse('myKey123');
var key = wordsToBytes(temp.words);
But no luck. Can you please someone help me where I am doing wrong. What is the right way to encrypt the file in javascript as same in C#?
This is the JavaScript code that would produce the same ciphertext as the C# code. The problem that remains is that you need to transmit this somehow.
var keyWords = CryptoJS.enc.Utf16LE.parse("myKey123");
var encryptedWords = CryptoJS.AES.encrypt("some string", keyWords, { iv: keyWords }).ciphertext;
console.log("Hex: " + encryptedWords.toString());
console.log("Base64: " + encryptedWords.toString(CryptoJS.enc.Base64));
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/components/enc-utf16-min.js"></script>

Android WebView send base64 url to Javascript (Refusing to load URL as it exceeds X characters.)

I'm trying to send a base64 image to javascript but I keep getting this error in Android Studio:
W/chromium: [WARNING:navigator_impl.cc(280)] Refusing to load URL as it exceeds 2097152 characters.
I've tried using loadDataWithBaseURL but I can't figure out how to make it actually run any Javascript so I'm not sure if that's a solution.
This is the code I'm using, it works for some images but some are too large and it gives me that error :(
Thanks for any help!
if (resultCode == RESULT_OK)
{
Uri selectedImage = intent.getData();
myWebView.loadUrl("javascript:setFileUri('" + selectedImage.toString() + "')");
String path = getRealPathFromURI(this, selectedImage);
//myWebView.loadUrl("javascript:setFilePath('" + path + "')");
Bitmap bm = BitmapFactory.decodeFile(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
myWebView.loadUrl("javascript:setFilePath('" + encodedImage + "')");
}
Don't know if you found an answer to this yet or not, but I was struggling with the same thing all day trying to send an image to Javascript. As with you, loadUrl was giving me the '2097152' error, so I tried using evaluateJavascript but kept getting webview syntax errors. After playing around with it, I finally got it to work like this:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
try {
final String retFunction = "imageReturnFunction('data:image/png;base64," + URLEncoder.encode(encoded, "UTF-8") + "');";
runOnUiThread(new Runnable() {
public void run() {
webView.evaluateJavascript(retFunction, null);
}
});
} catch(Exception ex) {
ex.printStackTrace();
}
Note that I needed it to be formatted as a dataURL in my case (which would be pretty common in a JS app), but you can adjust the code if needed. Hope this helps.
Based on bastecklein answer
val jsFunction = "$jsEntryPoint('data:image/jpeg;base64," +
base64String.replace("\n", "")
+"');"`
My answer was very late. But suddenly someone will come in handy.
When I had a problem, I decided to reduce the size of the string to be passed to the WebView.
Perhaps my solution will suit you:
public static String prepareImageForWebView(String img64) {
final int IMAGE_MAX_SIZE = 0x100000; // 1048576
if (img64.length() > IMAGE_MAX_SIZE) {
byte[] bytes = Base64.decode(img64, Base64.DEFAULT);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, o);
int scale = 1;
while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) {
scale++;
}
if (scale > 1) {
scale--;
// scale to max possible inSampleSize that still yields an image
// larger than target
o = new BitmapFactory.Options();
o.inSampleSize = scale;
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, o);
// resize to desired dimensions
assert bitmap != null;
int height = bitmap.getHeight();
int width = bitmap.getWidth();
double y = Math.sqrt(IMAGE_MAX_SIZE / (((double) width) / height));
double x = (y / height) * width;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, (int) x, (int) y, true);
bitmap.recycle();
bitmap = scaledBitmap;
System.gc();
}
if (bitmap == null) {
return img64;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, baos);
bytes = baos.toByteArray();
return Base64.encodeToString(bytes, Base64.DEFAULT);
} else {
return img64;
}
}
Use:
image = "<img style=\"display:inline;height:auto; max-width:100%;\" " +
"src=\"data:image/jpg; base64," +
prepareImageForWebView(imageData) + "\" />";
webView.loadData(image, "text/html", "UTF-8");
By changing IMAGE_MAX_SIZE, you can choose the size of the Base64 string that suits you at the output. For example, base64 with a size of 6 MB after recompression has sufficient quality for confident reading of the text in the A4 image

Categories