Storing image file in server file system using Image URI - javascript

I am getting URL from this Cordova Camera API and I am posting to WEBAPI. I tried with base64 but it increases the image size when I post it in server.
Please find my code below and suggest me how to save file to server.
//WEB API//
public IHttpActionResult UpdateUserDetails(ImageModel model)
{
try
{
if (model.ImageBase64 != "")
{
var PicDataUrl = "";
string ftpurl = "ftp://xxx.xxxxx.xxxx/";
var username = "xxx";
var password = "xxxxx";
string UploadDirectory = "xxxx/xx";
string FileName =model.ImageFileName;
String uploadUrl = String.Format("{0}{1}/{2}", ftpurl, UploadDirectory,FileName);
FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create(uploadUrl);
req.Proxy = null;
req.Method = WebRequestMethods.Ftp.UploadFile;
req.Credentials = new NetworkCredential(username, password);
req.EnableSsl = false;
req.UseBinary = true;
req.UsePassive = true;
// I am getting URI path like below and need to save this file in server
model.ImageBase64 = C:\Program Files (x86)\IIS Express\services5.jpg
byte[] data =Convert.FromBase64String(model.ImageBase64);
req.ContentLength = data.Length;
Stream stream = req.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
}
}
}
// I am getting URL from this Cordova Camera API and I am posting to WEBAPI
function onSuccessEdituserProfileGallery(imageData) {
console.log(imageData);
var smallImage
smallImage = document.getElementById('EdituserProfileImage');
smallImage.src = imageData;
customerImgData =smallImage.src;
return customerImgData;
}

usually i do this:
Back End:
[HttpPost]
[Route("Upload/Image")]
public async Task<IHttpActionResult> UploadImg()
{
try
{
#region VAR
if (!Directory.Exists(HttpContext.Current.Server.MapPath(string.Concat("~", Constant.Application.User_Cropped_Image_Directory)))) ;
Directory.CreateDirectory(HttpContext.Current.Server.MapPath(string.Concat("~", Constant.Application.User_Cropped_Image_Directory)));
string mapPath = HttpContext.Current.Server.MapPath(string.Concat("~", Constant.Application.User_Cropped_Image_Directory));
HttpRequestMessage request = this.Request;
String fileName = "";
#endregion VAR
#region SPLIT
// Get base64 string from POST
var base64String = request.Content.ReadAsStringAsync().Result;
// SPLIT Content from unecessary data
var split = base64String.Split(',');
var strings = split[1].Split('-');
#endregion SPLIT
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(strings[0]);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
if (!Directory.Exists(String.Concat(mapPath, fileName).ToLowerInvariant()))
Directory.CreateDirectory(String.Concat(mapPath, fileName).ToLowerInvariant());
fileName = GenericUtils.GetFileNameWithExt(image).ToLowerInvariant();
//name = String.Concat("croppedImage_", fileName);
image.Save(String.Concat(mapPath, fileName).ToLowerInvariant());
return Ok(new { data = String.Concat(Constant.Application.User_Cropped_Image_Directory, fileName).ToLowerInvariant() } );
}
catch (Exception ex)
{
_logger.LogException(ex);
return null;
}
}
Ionic (js):
$scope.takeFromCamera = function () {
document.addEventListener("deviceready", function () {
var options = {
quality: 90,
destinationType: Camera.DestinationType.DATA_URL,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
correctOrientation: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 600,
targetHeight: 600,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: true
};
if ($cordovaCamera)
$cordovaCamera.getPicture(options).then(function (imageData) {
$scope.imgURI = "data:image/jpeg;base64," + imageData;
//Image in Base64 to send to server for web profile
// var imgRaw = "data:image/jpeg;base64," + imageData;
$upload.upload({
url: enviroment.apiUrl + 'api/Upload/Image',
fields: { 'base64String': $scope.imgURI },
file: $scope.imgURI
}).success(function (data, status, headers, config) {
$scope.imageName = data.data;
$rootScope.$broadcast("update-img", { img: $scope.imageName });
});
}, function () {
$cordovaToast.show('Camera non Disponibile Si Prega di Riprovare piu tardi!', 'long', 'center');
});
}, false);
};

Related

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!

Error when printing PDF file in AngularJS

I am trying to print a PDF file generated through reportViewer in my Web API, but the browser shows an error when tries to open the PDF file.
This is the code inside the controller in my Web API:
// ...generate candidatosDataSet
LocalReport relatorio = new LocalReport();
string rootPath = HttpRuntime.AppDomainAppPath;
relatorio.ReportPath = rootPath + #"\Reports\Report.rdlc";
relatorio.DataSources.Add(new ReportDataSource("Candidatos", candidatosDataSet));
relatorio.Refresh();
byte[] relatorioBytes = ExportUtils.GerarArquivoPDF(relatorio);
response = Request.CreateResponse(HttpStatusCode.OK, relatorioBytes);
response.Content.Headers.ContentDisposition = System.Net.Http.Headers.ContentDispositionHeaderValue.Parse("attachment; filename=relatorio.pdf");
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
This is how I am generating PDF File through reportViewer
public static byte[] GerarArquivoPDF(LocalReport relatorio)
{
String reportType = "PDF";
String mimeType;
String encoding;
String fileNameExtension;
String deviceInfo;
Warning[] warnings;
string[] streams;
byte[] renderedBytes;
deviceInfo = "<DeviceInfo>" + " <OutputFormat>" + reportType + "</OutputFormat>" + "</DeviceInfo>";
renderedBytes = relatorio.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);
return renderedBytes;
}
Here is my AngularJS service method:
function obterTermoConfirmacaoCandidatura(candidatoId) {
return $http.get(configValues.baseUrl + 'candidato/GetRelatorio',
{
params: { candidatoId: candidatoId },
responseType: 'arraybuffer'
});
}
And this is the code that I am using to print the file on the AngularJS controller:
function imprimirTermoConfirmacaoCandidatura(id) {
CandidatoAPIService.obterTermoConfirmacaoCandidatura(id)
.then(function (response) {
var contentType = response.headers('Content-Type') || "application/octet-stream";
var file = new Blob([response.data], {
type: contentType
});
var fileUrl = URL.createObjectURL(file);
var printWindow = $window.open(fileUrl);
printWindow.print();
}, function (error) {
alert(error.data);
});
}
The response from Web API was comming as string, with double quotes in beginning and in the end of the response, so the PDF File could not be rendered correctly. Also I converted the response from server to base64, by this method:
function b64toBlob(b64Data, contentType) {
var sliceSize = 512;
b64Data = b64Data.replace(/"/g, '');
b64Data = b64Data.replace(/^[^,]+,/, '');
b64Data = b64Data.replace(/\s/g, '');
var byteCharacters = window.atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, { type: contentType });
return blob;
}
And changed the method on AngularJS controller to convert the response do base64:
function imprimirTermoAutorizacaoUsoImagem() {
CandidatoAPIService.obterTermoAutorizacaoUsoImagem()
.then(function (response) {
var contentType = response.headers('Content-Type') || "application/octet-stream";
var file = UtilsService.b64toBlob(response.data, "application/pdf");
var fileUrl = URL.createObjectURL(file);
var printWindow = $window.open(fileUrl);
printWindow.print();
}, function (error) {
alert(error.data);
});
}
And removed the responseType on the AngularJS service:
function obterTermoConfirmacaoCandidatura(candidatoId) {
return $http.get(configValues.baseUrl + 'candidato/GetObterTermoConfirmacaoCandidatura',
{
params: { candidatoId: candidatoId }
});
}

Send image socket io and android

I am a beginner in socket.io. I have been used a library
https://www.npmjs.com/package/socket.io-stream
We were successfully uploaded images using the browser. But now, I want to upload images from android application. If anyone have android code please give me ..
https://github.com/socketio/socket.io-client-java/issues/29
I have been searching on google, but not found any proper solution.
var imageBuffer = customJs.decodeBase64Image(base64Data);
var imageTypeDetected = imageBuffer.type.match(/\/(.*?)$/);
var filename = 'profile-' + Date.now() + '.' + imageTypeDetected[1];
// config.uploadImage --- Folder path where you want to save.
var uploadedImagePath = config.uploadImage + filename;
try {
fs.writeFile(uploadedImagePath, imageBuffer.data, function () {
dbMongo.updateImage({email: decoded.email, user_id: decoded.userId, 'profile_picture': config.showImagePath + filename}, function (res) {
if (res.error) {
socket.emit('set_update_image', {'error': 1, 'message': 'Error!' + res.message, 'data': null, 'status': 400});
} else {
console.log(res);
socket.emit('set_update_image', res);
}
});
});
} catch (e) {
socket.emit('set_update_image', {'error': 1, 'message': 'Internal server error ' + e, 'data': null, 'status': 400});
}
From other file call a function
exports.decodeBase64Image = function decodeBase64Image(dataString) {
var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
var response = {};
if (matches.length !== 3)
{
return new Error('Invalid input string');
}
response.type = matches[1];
response.data = new Buffer(matches[2], 'base64');
return response;
}
For the upload image from android using socket you need to send image as base64 string,
Following is the example for convert Image into base64 then you send data same as another paramaters.
String base64Image = getBase64Data(dirPath + "/" + fileName);
public String getBase64Data(String filePath) {
try {
InputStream inputStream = new FileInputStream(filePath);//You can get an inputStream using any IO API
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
while ((bytesRead = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
e.printStackTrace();
}
bytes = output.toByteArray();
return "data:image/jpeg;base64," + Base64.encodeToString(bytes, Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
In android, you need to encode the image by using Base64
public void sendImage(String path)
{
JSONObject sendData = new JSONObject();
try{
sendData.put("imageData", encodeImage(path));
socket.emit("image",sendData);
}catch(JSONException e){
}
}
private String encodeImage(String path)
{
File imagefile = new File(path);
FileInputStream fis = null;
try{
fis = new FileInputStream(imagefile);
}catch(FileNotFoundException e){
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,100,baos);
byte[] b = baos.toByteArray();
String encImage = Base64.encodeToString(b, Base64.DEFAULT);
//Base64.de
return encImage;
}
In server side, receive image and decode it
socket.on("image", function(info) {
var img = new Image();
img.src = 'data:image/jpeg;base64,' + info.imageData;
});

Length of uploaded couchDB attachment always 0 Bytes

So...I'm new to all this stuff and I'm developing an app for android with AngularJS and Ionic Framework and try to upload an audiofile I have recorded with the cordova capture Plugin like this:
// gets called from scope
$scope.captureAudio = function() {
var options = { limit: 1, duration: 10 };
$cordovaCapture.captureAudio(options).then(function(audioData) {
uploadFile(documentID, audioData);
}, function(err) {
console.log('error code: ' + err);
});
};
var uploadFile = function (document, file) {
var baseUrl = 'urltomydatabase';
var name = encodeURIComponent'test.3gpp'),
type = file[0].type,
fileReader = new FileReader(),
putRequest = new XMLHttpRequest();
$http.get(baseUrl + encodeURIComponent(document))
.success(function (data) {
putRequest.open('PUT', baseUrl + encodeURIComponent(document) + '/' + name + '?rev=' + data._rev, true);
putRequest.setRequestHeader('Content-Type', type);
fileReader.readAsArrayBuffer(file[0]);
fileReader.onload = function (readerEvent) {
putRequest.send(readerEvent);
};
putRequest.onreadystatechange = function (response) {
if (putRequest.readyState == 4) {
//success - be happy
}
};
})
.error(function () {
// failure
});
};
How the file looks in the console.log:
Playing the recorded file on the device works nice.
But everytime I upload the recording and the upload has finished, the uploaded attachment inside the document has the length '0' in the couchDB.
How the created file looks in the database after the upload:
What am I doing wrong?
EDIT: I just found out, when I upload an image, passed from this function as blob, it works well:
function upload(imageURL) {
var image = new Image();
var onload = function () {
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
canvas.toBlob(function (blob) {
uploadFile(documentID, blob);
});
};
image.onload = onload;
image.src = imageURL;
}
So maybe the solution is creating a blob from the audiofile? But everytime I try it, my blob has the size of 0 bytes even before uploading it and I don't find somewhere a great explanation of how to convert a MediaFile object to blob...
It looks like your code does not send the content of your file as multipart attachment. To see what is really send to couchdb, capture the traffic with wireshark (https://www.wireshark.org/) or such.
This thread brought me to the solution, PouchDB purifies it. Now my upload function looks like this and can handle every file format
// e.g capture Audio
$scope.captureAudio = function () {
var options = {limit: 1, duration: 10};
$cordovaCapture.captureAudio(options).then(function (audioData) {
uploadFile(documentID, audioData, 'audio');
}, function (err) {
console.log('error code: ' + err);
});
};
var uploadFile = function (id, file, mediatype) {
var fileName = makeID();
if (mediatype == 'image') var name = encodeURIComponent(fileName + '.jpg');
if (mediatype == 'audio') var name = encodeURIComponent(fileName + '.3gpp');
if (mediatype == 'video') var name = encodeURIComponent(fileName + '.3gp');
db.get(id).then(function (doc) {
var path = file.fullPath;
window.resolveLocalFileSystemURL(path, function (fileEntry) {
return fileEntry.file(function (data) {
var reader = new FileReader();
reader.onloadend = function (e) {
var blob = b64toBlobAlt(e.target.result, file.type);
if (blob) {
db.putAttachment(id, name, doc._rev, blob, file.type).then(function () {
if (mediatype == 'video' || mediatype == 'image') getMedia();
if (mediatype == 'audio') $scope.audios.push(source);
});
}
};
return reader.readAsDataURL(data);
});
});
});
};
// creating the blob from the base64 string
function b64toBlobAlt(dataURI, contentType) {
var ab, byteString, i, ia;
byteString = atob(dataURI.split(',')[1]);
ab = new ArrayBuffer(byteString.length);
ia = new Uint8Array(ab);
i = 0;
while (i < byteString.length) {
ia[i] = byteString.charCodeAt(i);
i++;
}
return new Blob([ab], {
type: contentType
});
}

webrtc audio record to python

I'm trying to record audio but the files as they are stored on server are only 10kb or less.
The file is being saved to server, and has the correct name, but is 10 kb or less.
In the browser the audio file is capable of being reviewed and plays as expected.
Server side python code:
def save_file(file, filename, path=''):
''' Little helper to save a file
'''
fd = open('%s/%s' % ('/root/ws911/media/', str(path) + str(filename)), 'wb')
#for chunk in file.chunks():
# fd.write(chunk)
fd.write(file)
fd.close()
JavaScript code excerpts:
// PostBlob method uses XHR2 and FormData to submit
// recorded blob to the PHP server
function PostBlob(blob, fileType, fileName) {
// FormData
var formData = new FormData();
formData.append(fileType + '-filename', fileName);
formData.append(fileType + '-blob', blob);
// POST the Blob using XHR2
xhr('xxxxxxxxxxxxxx/get_json/', formData, function(fileURL) {
});
}
var container = document.getElementById('container');
// var legalBufferValues = [256, 512, 1024, 2048, 4096, 8192, 16384];
// sample-rates in at least the range 22050 to 96000.
recordAudio = RecordRTC(stream, {
//bufferSize: 16384,
//sampleRate: 45000,
onAudioProcessStarted: function() {
if (!isFirefox) {
recordVideo.startRecording();
}
}
});
recordAudio.startRecording();
stop.disabled = false;
},
function(error) {
alert(JSON.stringify(error, null, '\t'));
});
};
var fileName;
stop.onclick = function() {
record.disabled = false;
stop.disabled = true;
preview.src = '';
fileName = Math.round(Math.random() * 99999999) + 99999999;
recordAudio.stopRecording(function(url) {
preview.src = url;
PostBlob(recordAudio.getBlob(), 'video', fileName + '.webm');
});
function xhr(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
callback(request.responseText);
}
};

Categories