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

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

Related

Spring/Javascript: Send canvas image as a MultipartFile using AJAX

I'm trying to send my canvas image to controller. I tried using ajax but it doesn't seem to work. Hope you can help me. This is my code.
function takeSnapshot() {
var video = document.querySelector('video')
, canvas;
var img = document.querySelector('img') || document.createElement('img');
var context;
var width = video.offsetWidth
, height = video.offsetHeight;
canvas = canvas || document.createElement('canvas');
canvas.width = width;
canvas.height = height;
context = canvas.getContext('2d');
context.drawImage(video, 0, 0, width, height);
img.src = canvas.toDataURL('image/png');
document.body.appendChild(img);
var dataURL = canvas.toDataURL('image/png');
var blob = dataURItoBlob(dataURL);
var fd = new FormData(document.forms[0]);
fd.append("uploadfile", blob, "test");
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/api/file/upload",
data: fd,
processData: false, //prevent jQuery from automatically transforming the data into a query string
contentType: false,
cache: false,
success: (data) => {
alert("shit");
},
error: (e) => {
alert("error");
}
});
}
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
}
And this is my controller that receives the submitted image.
#PostMapping("/api/file/upload")
public String uploadMultipartFile(#RequestParam("uploadfile") MultipartFile file) {
try {
fileStorage.store(file);
return "File uploaded successfully! -> filename = " + file.getOriginalFilename();
} catch (Exception e) {
return "Error -> message = " + e.getMessage();
}
}
I tried setting the value of input file type mannually but others said that it may lead to security problems. And I also I can't make it work. I want to do direct image capturing and save the image to server. I'm using spring and hibernate. Hoping you could help me. Thank you !!

Decode Image data in Android

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);

.NET C# exporting to excel via JS post using ExcelPackage

I'm not sure what I'm missing here. I've got a button that when clicked, I'm using javascript to call a controller. This controller should create an excel file and return it to the user giving them the ability to download/save the file. I've tried a few different methods, but can't manage to get it to work. Here's my javascript side:
function exportList() {
var val = $("#team-dropdown").val();
const date = new Date().toISOString();
const param = {
"Date": date,
"GroupID": 1
}
$.ajax({
url: "#Url.Action("ExportToExcel", "Home")",
type: "POST",
data: param
});
}
Here's my server side:
public FileResult ExportToExcel(DateTime date, int groupID)
{
Load l = new Load();
List<Load> loadList = l.GetLoadsForGroup(date, groupID);
var fileDownloadName = "fileName.xlsx";
var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("New workbook");
ws.View.ShowGridLines = true;
ws.DefaultColWidth = 25;
ws.Cells[1, 1].Value = "Order #";
var currRow = 2;
foreach (var load in loadList)
{
ws.Cells[2, 2].Value = load.LoadNumber;
}
var fs = new MemoryStream();
pck.SaveAs(fs);
fs.Position = 0;
var fsr = new FileStreamResult(fs, contentType);
fsr.FileDownloadName = fileDownloadName;
return (fsr);
}
Not sure what the best way to do this is. If there's a better way, please feel free to elaborate.
Your method looks fine. In that case you just need to use a html form to post instead of using the js function.
Alternatively, if you would like to use a ActionResult you can write:
public ActionResult ExportToExcel()
{
Load l = new Load();
List<Load> loadList = l.GetLoadsForGroup(date, groupID);
var fileDownloadName = "fileName.xlsx";
var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("New workbook");
ws.View.ShowGridLines = true;
ws.DefaultColWidth = 25;
ws.Cells[1, 1].Value = "Order #";
var currRow = 2;
foreach (var load in loadList)
{
ws.Cells[2, 2].Value = load.LoadNumber;
}
Response.Clear();
Response.ContentType = contentType;
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileDownloadName + "\"");
Response.BinaryWrite(pck.GetAsByteArray());
Response.Flush();
Response.End();
return View();
}
And you get the same result as your method.

Safari browsers sends blob/datauri as string in Node.js

I am trying to receive the file sent through AJAX. What's happening is that when the file sent using Chrome/Firefox the file goes to req.files but when it was sent using Safari, the file goes to req.params. The application treat the file as a string "[Object blob]". Thanks.
Sending userdata through ajax.
updatePartnerProfile: function(obj){
var parentObj = this;
var target = $(obj.target);
var parent = target.closest('#editPartnerDetailsForm');
var logoImg = parent.find('.cropped');
var companyLogoBase64 = logoImg.find('.croppedImage').attr('src');
var companyLogo = util.dataURItoBlob(companyLogoBase64);
var userData = new FormData();
userData.append('token', parentObj.token);
userData.append('companyLogo', companyLogo);
$.ajax({
type: 'POST',
url: parentObj.serverUrl + 'api/admin/update/organization/' + parentObj.partnerId,
processData: false,
contentType: false,
cache: false,
data: userData,
success: function(data){
//todo
}
},
error: function(err){
console.log(err);
}
});
},
dataURItoBlob : function(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
if (!_.isUndefined(dataURI)){
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
} else {
return null;
}
}
Am I missing something in the code?
Well, as per this question, you need to be using the buffer property of ia, not just [ia]. Instead of
return new Blob([ia], {type:mimeString});
try
return new Blob([ia.buffer], {type:mimeString});

Post Arraybuffer

I have following two methods that uploads an image to a remote servlet. For some reason the second parameter which is the arraybuffer is not written to the post request and I am trying to figure out why this is happening. Could some one assist me on this.
setupBinaryMessage = function(metadata) {
log(metadata);
var msglen = metadata.length;
var localcanvas =document.getElementById("image");
var fullBuffer;
var myArray;
if(localcanvas){
var localcontext = localcanvas.getContext('2d');
//FOLLOWING 2 LINE OF CODE CONVERTS THE IMAGEDATA TO BINARY
var imagedata = localcontext.getImageData(0, 0, localcanvas.width, localcanvas.height);
var canvaspixelarray = imagedata.data;
var canvaspixellen = canvaspixelarray.length;
var msghead= msglen+"";
var fbuflen = msglen +canvaspixellen+msghead.length;
myArray = new ArrayBuffer(fbuflen);
fullBuffer = new Uint8Array(myArray);
for (var i=0; i< msghead.length; i++) {
fullBuffer[i] = msghead.charCodeAt(i);
}
for (var i=msglen+msghead.length;i<fbuflen;i++) {
fullBuffer[i] = canvaspixelarray[count];
count++;
};
return myArray;
} else
return null;
};
upladlImageWithPost= function() {
var message =JSON.stringify(this.data);
var fullBuffer = this.setupBinaryMessage(message);
var formdata = {command : "post", imagedata : fullBuffer,};
alert(jQuery.isPlainObject( formdata ));
var imgPostRequest = $.post( "http://localhost:8080/RestClient/RestClientPOST",fullBuffer, function(response) {
response = response.trim();
console.log(response);
if(response == "SERVER_READY"){
alert(response);
try {
}catch (error) {
alert("Web Socket Error "+error.message);
}
} else {
alert("SERVER ERROR");
}
}.bind(this))
Alright After some help from a GURU I figured the issue. Apparently ARRAYBUFFER is obsolete and real solution is to post the unisinged buffer as it is. But even for that I need to set the AJAX response type to ARRAYBUFFER and then not use JQuery $.post but
use original pure XHTTPRequest.
Source

Categories