I am trying to convert the image into base64 but I get a null result, anyone has a clue? I found few examples how to take a pic from a camera and convert into b64 but i couldn't found anything how to convert image tag into b64.
<image #loaded="loaded" src="myimg.jpg">
var ImageSourceModule = require("tns-core-modules/image-source");
function loaded(args){
let imageSource = ImageSourceModule.fromNativeSource(args.object.nativeElement);
console.log(imageSource.toBase64String('jpeg'))
}
you might be getting null data because of coverting image before it is fully loaded. try converting image after it is fully loaded as shown in below snippet.
To convert image after it's load we are using loaded event and isLoading property of the Image.
loaded(args) {
console.log(args.eventName);
console.log(args.object);
var img = args.object;
console.log("img.isLoading: " + img.isLoading);
console.log("img.isLoaded: " + img.isLoaded);
if(img.isLoading){
img.on("isLoadingChange", function (args) {
console.log("isloading",args.value);
console.log("isloaded",args.object.isLoaded);
let img = args.object;
let imageSource= ImageSource.fromNativeSource(img);
console.log(imageSource.toBase64String('jpeg'))
});
}else if(!img.isLoading&&img.isLoaded){
let imageSource= ImageSource.fromNativeSource(img);
console.log(imageSource.toBase64String('jpeg'))
}else{
console.log("image loading failed");
}
}
Related
After reading an image with the ImageDescriptor API and resizing it by instantiating a codec I am trying to write the resized version in the application directory.
I saw that the when converting the frame into byte data I have a format which is rawUnmodified which I assumed would write the resized image in the same format as the original image. But when I tried to load the resized image I get an image format exception.
Example code:
//read the original image and obtain the image descriptor
var imageData = await file.readAsBytes();
final ImmutableBuffer buffer = await ImmutableBuffer.fromUint8List(imageData);
final imDescr = await ImageDescriptor.encoded(buffer);
//resize the image, get the first frame and convert it to bytes
Codec codec = await imDescr.instantiateCodec(targetWidth: 100, targetHeight: 100);
FrameInfo frameInfo = await codec.getNextFrame();
var bytes = await frameInfo.image.toByteData(
format: ImageByteFormat.rawUnmodified,
//note when using the png format it works, but I would like to have it in the original image format(in this case its jpg)
);
//write the resized image
Directory appDir = await getApplicationDocumentsDirectory();
var path = appDir.path;
var file = File('$path/test1.jpg');
await file.writeAsBytes(bytes.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes));
In the ImageByteFormat api it says: rawUnmodified -> Unencoded bytes, in the image's existing format. For example, a grayscale image may use a single 8-bit channel for each pixel.
But when I try to show this image the format is wrong. Anybody have an idea how to fix this?
Why use image ImageDescriptor, You can do it easily by image package
File resizeImage(File imageFile, String imageFormat, int targetWidth, int targetHeight) {
im.Image tempImage = im.decodeImage(imageFile.readAsBytesSync());
tempImage = im.bakeOrientation(tempImage);
tempImage = im.copyResize(tempImage, width: targetWidth, height: targetHeight);
File newImage;
if (imageFormat == 'jpg') {
newImage = File('newpath/test.jpg');
newImage.writeAsBytesSync(im.encodeJpg(tempImage));
return newImage;
} else if (imageFormat == 'png') {
newImage = File('newpath/test.png');
newImage.writeAsBytesSync(im.encodePng(tempImage));
return newImage;
} else {
throw ('Unknown Image Format');
}
}
I had functionality to pick an image of QRcode from CameraRoll of Android and iOS in react-native and once the user had picked an image. I will use something like jsQR to decode that and validate if its a real qr code or not.
But on jsQR lib they said that they need to accept Uint8ClampedArray to decode the image and read the qr. So I already have a function to get the base64 image. But can't find on how to convert it properly to Uint8ClampedArray.
Here is my code below:
const handleImportScan = useCallback(async () => {
try {
const base64Image = await RNFS.readFile(
photos[selected].node.image.uri,
'base64',
);
console.log('base64img:', base64Image);
// First argument below should be a 'Uint8ClampedArray'
const code = jsQR(base64Image, width, height);
if (code) {
console.log('Found QR code', code);
}
} catch (error) {
console.log('err:', error);
}
}, [photos, selected]);
I'm trying to find a library or third-party to convert my base64 image to Uint8ClampedArray
Mostly I save the user qr generate images using PNG.
Appreciate it if someone could help.
Thanks
Note that base64data should be base64 encoded image not uri. (eg. without 'data:image/png;base64,', if you have uri)
const byteCharacters = atob(base64data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8ClampedArray(byteNumbers);
I have a scenario where I need to save an image from the <Image /> tag to the local file. The code does save the image to the file but i get an empty image, I know it's sound simple but I am new to NS and couldn't find anything on google, maybe someone knows why?
XML:
<page>
<image src="pic.png" id="img"/>
</page>
JS:
let img = page.getViewById("img");
let path = fs.path.join(fs.knownFolders.documents().path, "pic.png");
let src = ImageSource.fromNativeSource(img);
let saved = src.saveToFile(path, "png");
you might be getting empty image because of saving image before it is fully loaded. try saving image after it is fully loaded as shown in below snippet.
To save image after it's load we are using loaded event and isLoading property of the Image.
XML:
<page>
<image src="pic.png" loaded="onImageLoaded" id="img"/>
</page>
TS:
onImageLoaded(args) {
console.log(args.eventName);
console.log(args.object);
var img = args.object;
console.log("img.isLoading: " + img.isLoading);
console.log("img.isLoaded: " + img.isLoaded);
if(img.isLoading){
img.on("isLoadingChange", function (args) {
console.log("isloading",args.value);
console.log("isloaded",args.object.isLoaded);
let img = args.object;
let path = fs.path.join(fs.knownFolders.documents().path, "pic.png");
let src = ImageSource.fromNativeSource(img);
let saved = src.saveToFile(path, "png");
});
}else if(!img.isLoading&&img.isLoaded){
let path = fs.path.join(fs.knownFolders.documents().path, "pic.png");
let src = ImageSource.fromNativeSource(img);
let saved = src.saveToFile(path, "png");
}else{
console.log("image loading failed");
}
}
i am using Image Intervention and jcrop to crop and resize image in laravel, but having problems. The issue which i think is that , when i save the file width and height is correct according to the selection, but the x & y is not correct, I am completely lost here, dont know what to do , Please help.
I have made but cropping area is wrong.
here is the code example.
// convert bytes into friendly format
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
}
// check for selected crop region
function checkForm() {
if (parseInt($('#w').val())) return true;
$('.setting-image-error').html('Select area').show();
return false;
}
// update info by cropping (onChange and onSelect events handler)
function updateInfo(e) {
$('#x1').val(e.x);
$('#y1').val(e.y);
$('#x2').val(e.x2);
$('#y2').val(e.y2);
$('#w').val(e.w);
$('#h').val(e.h);
}
// clear info by cropping (onRelease event handler)
function clearInfo() {
$('#w').val('');
$('#h').val('');
}
// Create variables (in this scope) to hold the Jcrop API and image size
var jcrop_api, boundx, boundy;
function fileSelectHandler() {
// get selected file
var oFile = $('#picture')[0].files[0];
// hide all errors
$('.setting-image-error').hide();
// check for image type (jpg and png are allowed)
var rFilter = /^(image\/jpeg|image\/png)$/i;
if (!rFilter.test(oFile.type)) {
$('.setting-image-error').html('Select only jpg, png').show();
return;
}
// check for file size
if (oFile.size > 10000000) {
$('.setting-image-error').html('Too Big file ').show();
return;
}
// preview element
var oImage = document.getElementById('preview');
// prepare HTML5 FileReader
var oReader = new FileReader();
oReader.onload = function (e) {
// e.target.result contains the DataURL which we can use as a source of the image
oImage.src = e.target.result;
oImage.onload = function () { // onload event handler
// display step 2
$('.setting-image-cropping-stage').fadeIn(500);
// display some basic image info
var sResultFileSize = bytesToSize(oFile.size);
$('#filesize').val(sResultFileSize);
$('#filetype').val(oFile.type);
$('#filedim').val(oImage.naturalWidth + ' x ' + oImage.naturalHeight);
// destroy Jcrop api if already initialized
if (typeof jcrop_api !== 'undefined') {
jcrop_api.destroy();
jcrop_api = null;
$('#preview').width(oImage.naturalWidth);
$('#preview').height(oImage.naturalHeight);
}
//Scroll the page to the cropping image div
$("html, body").animate({scrollTop: $(document).height()}, "slow");
// initialize Jcrop
$('#preview').Jcrop({
minSize: [32, 32], // min crop size
aspectRatio: 1, // keep aspect ratio 1:1
bgFade: true, // use fade effect
bgOpacity: .3, // fade opacity
onChange: updateInfo,
onSelect: updateInfo,
onRelease: clearInfo
}, function () {
// use the Jcrop API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the Jcrop API in the jcrop_api variable
jcrop_api = this;
});
}
}
// read selected file as DataURL
oReader.readAsDataURL(oFile);
}
and Controller code is below.
public function image_crop_resize_and_upload($file, $user_id,$width,$height,$x1,$y1)
{
$filename = $user_id . '.jpg';// image file name
$target_path = User::PICTURE_PATH . $filename;//path where to create picture with new dimensions
$img = \Image::make($file->getRealPath());// create the instance of image with the real path of the image
$filetype = $img->mime();//get file mime type
$filetypes = ['image/jpg', 'image/jpeg', 'image/png']; //allowed files types
//if file exists in the target folder, system will delete the file and next step will create new one.
if (File::exists($target_path)) {
File::delete($target_path);
}
if (in_array($filetype, $filetypes, true)) {
$img->crop($width, $height,$x1,$y1);
$img->encode('jpg', 85);
$img->resize($width,$height);
$img->save('uploads/' . $user_id . '.jpg');
return true;
} else {
return false;
}
}
When i have the file the file width and height is correct, but the selection area, x & y is not correct.
Yes , I have got the answer. The problem is very simple the x and y position of image are wrong because it is inside a bootstrap responsive class. the proper solution is just to remove the class . So the image actually dimension will be shown. and than select the are. Thats it.
<img id="preview" name="preview" class="img-responsive"/>
this should be
<img id="preview" name="preview"/>
UPDATE
now its working, see the answer below (https://stackoverflow.com/a/43983621/2844901)
this is my getDrawing function, I need to save the signature from drawing to a file in file system, I've tried everything and I cant get the saveToFile demo in nativescript docs to get it work.
exports.getDrawing = function(args) {
var pad = frameModule.topmost().currentPage.getViewById("drawingPad");
// then access the 'drawing' property (Bitmap on Android) of the signaturepad
var img = frameModule.topmost().currentPage.getViewById("imagesignature");
pad.getDrawing().then(function(result){
img.src = result; // <-- this shows in an image label the drawing signature
########### this part should be save the file,but I don't get any error, and it doesn't save it to a file, when tried to dump "img" ############
var img2 = imageSource.fromAsset(result);
var folder = fs.knownFolders.documents();
var path = fs.path.join(folder.path, "Test.png");
var saved = img2.saveToFile(path, "png");
});
}
the problem was, the getDrawing() does not return a promise it returns an image so the correct code should be a NativeSource.
pad.getDrawing().then(function(result){
img.src = result;
console.log("1");
var img2 = imageSource.fromNativeSource(result);
var folder = fs.knownFolders.documents();
var path = fs.path.join(folder.path, "Test.png");
var saved = img2.saveToFile(path, "png");
console.log("saved: " + saved);
console.log("IMAGEN SRC.....");
});