Nativescript plugin "nativescript-camera-plus": Can´t set Picture Size (width and height) - nativescript

Hello iam developing a nativescript app and im using the "nativescript-camera-plus" plugin (Plugin on Github: https://github.com/nstudio/nativescript-camera-plus), even setting the parameters (width and height) exactly as described in the Option Interfaces section:
cam.takePicture({ saveToGallery: true, confirm: false, keepAspectRatio: true, width: 1920, height: 1440 });
...the plugin takes the picture and saves it, taking as reference the screen resolution of the mobile device divided by 2. Example: If the screen resolution is 1920, the plugin divides by 2 and saves the photo in 960. I need it save the photo with the width and height size that I determined in the options (parameters) of the code. Can someone help me?
MY CODE:
exports.takePicFromCam = function (args) {
cam.requestCameraPermissions().then(function () {
if (!cam) {
cam = new CameraPlus();
}
cam.takePicture({ saveToGallery: true, confirm: false, keepAspectRatio: true, width: 1920, height: 1440 });
});
}
cam.on(CameraPlus.photoCapturedEvent, function (args) {
fromAsset(args.data)
.then(function (res) {
var preview = topmost().getViewById('testImagePickResult');
var picture = res;
var matrix = new android.graphics.Matrix();
matrix.postRotate(180);
var imagemfinal = android.graphics.Bitmap.createBitmap(picture.android, 0, 0, picture.android.getWidth(), picture.android.getHeight(), matrix, true);
preview.src = imagemfinal;
var novonomedafoto = new Date().getTime();
});
imagemsource = page.getViewById("testImagePickResult").imageSource;
const folderDest = fileSystemModule.knownFolders.currentApp();
const pathDest = fileSystemModule.path.join(folderDest.path, "photos/" + novonomedafoto + ".jpg");
const saved = imagemsource.saveToFile(pathDest, "jpg");
if (saved) {
console.log("Image saved successfully!");
}
});
exports.onNavigatingTo = onNavigatingTo;

The plugin do not write the file with the width & height you proposed but instead it just returns the resized image asset (data) that holds the Bitmap with your width & height spec.
data.getImageAsync((bitmap, error) => {
// Use `bitmap` (android.graphics.Bitmap)
});

Related

Nuxt SSR return loaded image dimensions to server

I'm trying to preview a profile photo on an existing img element my problem is that the new image dimension become undefined outside of the img load function.
How can i pass these dimensions to the server so that i can properly resize the img element?
I've tried using Vuex Store as well to pass the dimensions but with the same undefined results.
I also have a function that listens for resize and after a user changes the window the img is resized properly, however i'm trying to do this without the event trigger. Even when i try to manually trigger the resize event with jQuery it does not resize. I'm under the impression that somehow the dimension of the new img source are not being set properly until a resize even refreshes the dimensions?
<b-img id="profilePhoto" v-bind="profile" :src="this.photo" class="profilePhoto" #change="handleResize()"></b-img>
export default {
data() {
return {
errors:{},
profile: {},
fileDimensions: {},
photo: '',
form: this.$vform({
id: '',
name: '',
email: '',
password: '',
role: '',
bio: '',
photo: ''
})
}
}
}
getPhoto(e) {
let file = e.target.files[0];
if (typeof file !== 'undefined'){
let reader = new FileReader()
let limit = 1024 * 1024 * 2
if (file.size > limit) {
return false;
}
reader.onloadend = (file) => {
this.form.photo = reader.result
this.photo = this.form.photo
}
reader.readAsDataURL(file)
$("<img/>",{
load : function(){
// will return dimensions fine if i use alert here
this.fileDimensions = { width:this.width, height:this.height} ;
},
src : window.URL.createObjectURL(file)
});
// becomes undefined outside of the load functions
var aw = this.fileDimensions.width
var ah = this.fileDimensions.height
var ph = $('.profile').height()
var pw = $('.profile').width()
console.log(this.fileDimensions.width)
if (ah>aw){
this.profile = { width: ph, height: 'auto'}
} else if (aw>ah) {
this.profile = { width: 'auto', height: ph}
} else {
this.profile = { width: ph+10, height: pw+10}
}
}
}
I expect to get the dimensions so i can determine how to set the width and height properties for the img element with its new src however the dimension become undefined.
I figured it out through another post. I had to create a promise. async await in image loading
getDimensions(src){
return new Promise((resolve,reject) => {
let img = new Image()
img.onload = () => resolve({ height: img.height, width: img.width })
img.onerror = reject
img.src = src
})
},
getPhoto(e) {
let file = e.target.files[0];
if (typeof file !== 'undefined'){
let reader = new FileReader()
let limit = 1024 * 1024 * 2
if (file.size > limit) {
return false;
}
reader.onloadend = (file) => {
this.form.photo = reader.result
this.photo = this.form.photo
}
reader.readAsDataURL(file)
this.getDimensions(URL.createObjectURL(file))
.then((dimensions) => {
if (process.client){
var ah = $('.profile').height()
var aw = $('.profile').width()
var ph = dimensions.height
var pw = dimensions.width
if (ph>pw){
this.profile = { width: ah+10, height: 'auto'}
} else if (pw>ph) {
this.profile = { width: 'auto', height: ah+10}
} else {
this.profile = { width: ah+10, height: aw+10}
}
}
})
}
}

Aframe: size of model

When using a model as a source to an entity, say gltf, is there a way we know the original size? Since the scale attribute works on relative size, it seems to be a trial an error to fit the model to our desired size. I tried using the geometry.getComputingBox() of the mesh of the model but it returns null. Wondering if there is a component that is available that lets us specify the scale in absolute terms.
Ah, figured it out.
var model = this.el.object3D;
var box = new THREE.Box3().setFromObject( model );
var size = box.getSize();
gives you the size. then using the above any desired size can be set.
Created a simple component that can be conveniently used
AFRAME.registerComponent('resize', {
schema: {
axis: {
type: 'string',
default: 'x'
},
value: {
type: 'number',
default: 1
}
},
init: function() {
var el = this.el;
var data = this.data;
var model = el.object3D;
el.addEventListener('model-loaded', function(e) {
var box = new THREE.Box3().setFromObject( model );
var size = box.getSize();
var x = size.x;
var y = size.y;
var z = size.z;
if(data.axis === 'x') {
var scale = data.value / x;
}
else if(data.axis === 'y') {
var scale = data.value / y;
}
else {
var scale = data.value / z;
}
el.setAttribute('scale', scale + ' ' + scale + ' ' + scale);
});
}
});
And it can be used as to proportionately resize the model with x axis length as 0.5
<a-entity resize='axis:x; value:0.5' gltf-model='#model`></a-entity>
(This would have come as a comment but as I don't have enough rep points this is coming as an answer.)
I found that the model doesn't have a size directly after the model-loaded event listener so I trigger the rescale from the update method. Funnily enough though if you don't have the model-loaded event listener then the size of the model will be 0 even after the first update is fired.
This is my variant of the above code with the difference being that the dimension is set in meters:
/**
* Scales the object proportionally to a set value given in meters.
*/
AFRAME.registerComponent("natural-size", {
schema: {
width: {
type: "number",
default: undefined, // meters
},
height: {
type: "number",
default: undefined, // meters
},
depth: {
type: "number",
default: undefined, // meters
},
},
init() {
this.el.addEventListener("model-loaded", this.rescale.bind(this));
},
update() {
this.rescale();
},
rescale() {
const el = this.el;
const data = this.data;
const model = el.object3D;
const box = new THREE.Box3().setFromObject(model);
const size = box.getSize();
if (!size.x && !size.y && !size.z) {
return;
}
let scale = 1;
if (data.width) {
scale = data.width / size.x;
} else if (data.height) {
scale = data.height(size.y);
} else if (data.depth) {
scale = data.depth / size.y;
}
el.setAttribute("scale", `${scale} ${scale} ${scale}`);
},
remove() {
this.el.removeEventListener("model-loaded", this.rescale);
},
});
Then:
<a-entity natural-size='width:0.72' gltf-model='#model`></a-entity>
box.getSize has changed, I combined what I found here with what I found in another answer and noticed in the console to produce a more minimalist answer just to determine the size itself of a model:
getDimensions(object3d) {
// e.g., object3d = document.querySelector('#goban').object3D
var box = new THREE.Box3().setFromObject( object3d );
var x = box.max.x - box.min.x
var y = box.max.y - box.min.y
var z = box.max.z - box.min.z
return {x,y,z}
}

Fineuploader drawThumbnail with Pica

I'm new to Fineuploader and using this great uploader together with Pica for image scaling. Pica works well for scaling and thumbnails.
scaling: {
sendOriginal: false,
hideScaled: false,
sizes: [
{name: "a", maxSize: 200},
{name: "b", maxSize: 600},
{name: "c", maxSize: 1000}
],
customResizer: !qq.ios() && function(resizeInfo) {
return new Promise(function(resolve, reject) {
pica.debug = console.log.bind(console),
pica.resizeCanvas(resizeInfo.sourceCanvas, resizeInfo.targetCanvas, {}, resolve)
})
}
}, thumbnails: {
customResizer: !qq.ios() && function(resizeInfo) {
return new Promise(function(resolve, reject) {
pica.resizeCanvas(resizeInfo.sourceCanvas, resizeInfo.targetCanvas, {}, resolve)
})
}
}
However, I need to drawThumbnail to other places. I've tried googling all around and going through the Fineuploader's documentation, but still no luck in making Pica run with drawThumbnails.
Fineuploader's documentation
drawThumbnail (id, targetContainer[, maxSize[, fromServer[, customResizer]]])
My current code
var canvas = document.createElement('canvas');
canvas.width = 300;
canvas.height = 200;
$(".frame").html(canvas);
uploader.drawThumbnail(id, canvas, 300, false);
It would be great if someone could guide me on modifying the current code to make drawThumbnail run with Pica, thanks.
As you pointed out in your question, the documentation shows how to use an alternate resizer function when using drawThumbnail:
drawThumbnail(id, targetContainer[, maxSize[, fromServer[, customResizer]]])
...so, your code would look like this:
var canvas = document.createElement('canvas')
var customResizer = function(resizeInfo) {
return new Promise(function(resolve, reject) {
pica.resizeCanvas(
resizeInfo.sourceCanvas,
resizeInfo.targetCanvas,
{},
resolve
)
})
}
canvas.width = 300;
canvas.height = 200;
$(".frame").html(canvas);
uploader.drawThumbnail(id, canvas, 300, false, !qq.ios() && customResizer);

How to select all features in cluster layer in openlayers 3

I've got a simple code and a simple map with adding features and clustering them all together. Straight from example:
var vectorSource = new ol.source.Vector({
projection: 'EPSG:4326'
});
var clusterSource = new ol.source.Cluster({
distance: 30,
source: vectorSource
});
var styleCache = {};
var clusters = new ol.layer.Vector({
source: clusterSource,
style: function(feature, resolution) {
var size = feature.get('features').length;
var style = styleCache[size];
var src;
if (!style) {
if( size == 1 ){
src = 'images/location-single.png';
}else{
src = 'images/location-multi.png';
}
style = [
new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: '#5bc0de'
})
})
}),
new ol.style.Style({
image: new ol.style.Icon(({
// scale: 1 + rnd,
// rotateWithView: (rnd < 0.9) ? true : false,
// rotation: 360 * rnd * Math.PI / 180,
anchor: [0.45, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
// opacity: rnd,
src: src
})),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#000'
})
})
})
];
styleCache[size] = style;
}
return style;
}
});
var map = new ol.Map({
target: 'map', // The DOM element that will contains the map
renderer: 'canvas', // Force the renderer to be used
layers: [
// Add a new Tile layer getting tiles from OpenStreetMap source
new ol.layer.Tile({
source: new ol.source.OSM()
}),
clusters
],
// Create a view centered on the specified location and zoom level
view: new ol.View({
center: ol.proj.transform([2.1833, 41.3833], 'EPSG:4326', 'EPSG:3857'),
zoom: 6
})
});
Now i got cluster function working fine. But i need to show coordinates for every point in the cluster, i've tryed to use map.forEachFeatureAtPixel, but it doesent work for ALL the features in the cluster. How do i select them all?
Oh. I think i got it! A cluster is a feature and got its properties. so we can GET all features in a cluster by using .getProperties()
as in:
map.on('singleclick', function(event) {
map.forEachFeatureAtPixel(event.pixel, function(feature) {
var featuresInCluster = feature.getProperties().features;
});
});
But i would really like to know if is there another way?
/***First create a select interaction object by assigning the cluster layer you created**/
var select = new ol.interaction.Select({
layers: [clusters]
});
/**Then add the created select object**/
map.addInteraction(select);
var selectedFeatures = select.getFeatures();
/**Then write this code**/
selectedFeatures.on('add', function (event) {
// event.target only contains the clustered point
var feature = event.target.item(0);
console.log(feature)
});
/***HOPE IT WILL WORK**//

Rotating around origin - Famo.us

How can I rotate ImageSurface around it's origin if I have applied translate to it ?
It does not rotate around origin. Can someone explain me is it using "align point" as center of rotation ?
EDIT
My ImageSurface is rotating like it has distante point of rotation and it scales up.
function _createFb() {
this.fbLogo = new ImageSurface({
size : [true, true],
content : 'images/fb.png',
properties: {
zIndex: 10
}
});
var fbModifier = new StateModifier({
origin: [0.5,0.5],
align:[0.5,0.5],
transform: Transform.scale(0.4,0.4,1)
});
var fbPosModifier = new StateModifier({
transform: Transform.translate(-250,520,0)
});
this.fbLogo.on("mouseleave", function(){
fbModifier.setTransform(Transform.rotateZ(Math.PI/4), { duration: 1000});
});
this.layout.content.add(fbModifier).add(fbPosModifier).add(this.fbLogo);
}
MY SOLUTION
function _createFb() {
this.fbLogo = new ImageSurface({
size : [true, true],
content : 'images/fb.png',
properties: {
zIndex: 10
}
});
var fbModifier = new StateModifier({
origin: [0.5,0.5],
align:[0.5,0.5],
transform: Transform.scale(0.4,0.4,1)
});
var fbPosModifier = new StateModifier({
transform: Transform.translate(-250,520,0)
});
var fbRotateModifier = new Modifier();
var transitionable = new Transitionable(0);
this.fbLogo.on("mouseleave", function(){
transitionable.reset(0);
fbRotateModifier.transformFrom(function(){
return Transform.rotateZ(transitionable.get());
}
);
transitionable.set(2 * Math.PI, {curve: "inOutQuad", duration: 500});
});
this.layout.content.add(fbModifier).add(fbPosModifier).add(fbRotateModifier).add(this.fbLogo);
}
This can be done using straight Famo.us, no need to modify CSS. Here's an example. Some of these modifiers can be combined, but I'm breaking them up for clarity. Centering the origin is first applied to a Surface. Rotations now pivot about the newly defined origin. Then the rotated Surface is translated.
var surface = new Surface({
size : [100,100],
properties : {background : 'red'}
});
var translateModifier = new Modifier({
transform : Transform.translate(100,0,0)
});
//rotates around and around based on your current system time
var rotateModifier = new Modifier({
transform : function(){ return Transform.rotateZ(Date.now() * .001) }
});
var centerModifier = new Modifier({
origin : [.5,.5]
});
context
.add(translateModifier)
.add(rotateModifier)
.add(centerModifier)
.add(surface)
I had similar problems to spin an element. The transform origin needs to be set center (50% 50%). I used css class for this.
.myClass {
-webkit-transform-origin: 50% 50% !important;
}
var myElem = new Surface({
size: [40, 40],
classes: ['myClass']
});
this.myElemModifier = new StateModifier();
// called from user action
this.myElemModifier.setTransform(
Transform.rotateZ(Math.PI), { duration: 5000 }
);

Resources