I am actually implementing a function to allow user to upload the photos from phone.
Is there any image compress plugin / library to recommended?
Notes: it is image compression, not image resizing.
Thanks a lot
Use the Ionic Native Camera function
There is a quality option ranging from 0-100. It will return a compressed image
const options: CameraOptions = {
quality: 50, // Try changing this
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
let base64Image = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
// Handle error
});
Try following CameraOptions with ionic camera plugin.
const options: CameraOptions = {
quality: 20,
targetWidth: 600,
targetHeight: 600,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.PNG,
mediaType: this.camera.MediaType.PICTURE,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
allowEdit: true //may not work with some deices
}
It is targetHeight and targetWidth doing the magic. :)
Answer referred from : Ionic image compress
Related
I read all docs I could and searched all over the internet attempting to achieve the following (attached image) on ChartJS 3.9.1. Is it even possible to have each axis on a radar chart labeled on ChartJS?
radar chart
I had the same problem as you and found this solution:
Define the array of base64 images you want as labels
const labelImages = [
/* Image 2 */ 'data:image/png;base64,iVBORw0KGg......',
/* Image 1 */ 'data:image/png;base64,iVBORw0KGgoAA.....'
]
Then use the plugin:
plugins: [
{
id: 'Label images',
afterDraw: (chart) => {
for (const i in chart.scales.r._pointLabelItems) {
const point = chart.scales.r._pointLabelItems[i];
var image = new Image();
image.src = labelImages[i];
// you I had 20x20 images thats why I use 20x20
chart.ctx.drawImage(image, point.x - 10, point.y, 20, 20);
}
}
}
]
Draw image from context options
This solution draws images where the labels are (where they start, i think), if you want only images and no text then you should hide the labels. I did it like this:
options: {
// just so that the images are not outside the canvas
layout: {
padding: 20
},
scales: {
y: {
display: false
},
x: {
display: false
},
r: {
pointLabels: {
// Hides the labels around the radar chart but leaves them in the tooltip
callback: function (label, index) {
return ' ';
}
}
}
}
}
I hope this helps
I am open to learning that there is already a way (via configuration, or developing a plugin) to hook into the rendering of the label of an axis, such that I could control aspects of the font used to render each line of a multiline label (e.g., what I need to render would be similar visually to a label and sub-label below it, with the primary label being bolded and a larger font size, while the sub-label directly beneath it would be normal font weight and a smaller size).
I am using ChartJs version 3.5.1 to render a horizontal barchart (meaning that the dataset labels on the left are really configured under the y axis), and have tried a few different things already:
Hooking into the tick callback - but I can't even use this function to duplicate default functionality (the value coming into that function isn't the label text; instead it is the index/ordinal of the data row?). Even if I could get this to work as shown in examples, it appears like this would be more for the content of the label than any of the configuration options themselves.
Setting the font configuration for ticks to be an array - but this only serves to allow me to change the font between data rows (e.g., I can make the label of the top row in my horizontal bar chart be size 22, the second label 10, etc. - but not change font attributes within lines of a given label)
Using a plugin like afterDraw to try to go tweak things - but again, the configuration at that point seems to only consider all of the lines together as one label.
Tried looking through past PRs to the project (mostly centered around adding multiline label support, as well as bug fixes specific to that area) to get any additional insight
If there isn't a way currently (via plugins or existing configuration), does anyone have a good feel for where to start attacking this sort of a change as a new PR?
UPDATE
As was shared as a response to my corresponding ChartJs feature request and as the accepted answer below, a custom plugin seems to be the only way currently to accomplish what I wanted for now.
Here are the key bits from my configuration (admittedly much more "one time use only" than the accepted answer, as I moved some of the configuration inside of the plugin as hard-coded values given my relatively narrow use case):
// this will be passed into the chart constructor...
const options = {
//...
scales: {
//...
// I wanted to impact the lefthand side of a horizontal bar chart
y: {
ticks: {
// make the original labels white for later painting over with custom sub-labels
color: "white",
// we still want this here to be able to take up the same space as the eventual label we will stick here
font: {
size: 22,
weight: "bold"
}
}
},
//...
}
};
// This is my plugin, also later passed into the chart constructor
const customSubLabelsPlugin = {
id: "customSubLabels",
afterDraw: (chart, args, opts) => {
// Set all variables needed
const {
ctx,
// I only cared about altering one specific axis
scales: { y }
} = chart;
const labelItems = y._labelItems;
const fontStringSubTitle = "16px Helvetica,Arial,sans-serif";
const fontStringMain = "bold 22px Helvetica,Arial,sans-serif";
// loop over each dataset label
for (let i = 0; i < labelItems.length; i++) {
let labelItem = labelItems[i];
// For purposes of redrawing, we are going to always assume that each label is an array - because we make it that way if we need to
const label = Array.isArray(labelItem.label)
? labelItem.label
: [labelItem.label];
// Draw new text on canvas
let offset = 0;
label.forEach((el) => {
let elTextMetrics = ctx.measureText(el);
if (labelItem.label.indexOf(el) === 0) {
ctx.font = fontStringMain;
} else {
ctx.font = fontStringSubTitle;
}
ctx.save();
ctx.fillStyle = "#546a6f";
ctx.fillText(
el,
labelItem.translation[0],
labelItem.translation[1] + labelItem.textOffset + offset
);
ctx.restore();
offset +=
elTextMetrics.fontBoundingBoxAscent +
elTextMetrics.fontBoundingBoxDescent;
});
}
}
};
You can use a plugin to redraw the ticks for you, might need some finetuning for your specific needs:
var options = {
type: 'line',
data: {
labels: [
["Red", "subTitle"],
["Blue", "subTitle"],
["Yellow", "subTitle"],
["Green", "subTitle"],
["Purple", "subTitle"],
["Orange", "subTitle"]
],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'red',
backgroundColor: 'red'
}]
},
options: {
plugins: {
customTextColor: {
color: 'blue',
boxColor: 'white',
fontStringSubTitle: 'italic 12px Comic Sans MS',
fontStringMain: ''
}
}
},
plugins: [{
id: 'customTextColor',
afterDraw: (chart, args, opts) => {
// Set all variables needed
const {
ctx,
scales: {
y,
x
}
} = chart;
const labelItems = x._labelItems;
const {
color,
boxColor,
fontStringMain,
fontStringSubTitle
} = opts;
const defaultFontString = '12px "Helvetica Neue", Helvetica, Arial, sans-serif';
for (let i = 0; i < labelItems.length; i++) {
let labelItem = labelItems[i];
if (!Array.isArray(labelItem.label)) {
continue;
}
let metrics = ctx.measureText(labelItem.label);
let labelWidth = metrics.width;
let labelHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
//Draw box over old labels so they are inviseble
ctx.save();
ctx.fillStyle = boxColor || '#FFFFFF';
ctx.fillRect((labelItem.translation[0] - labelWidth / 2), labelItem.translation[1], labelWidth, labelHeight * labelItem.label.length);
ctx.restore();
// Draw new text on canvas
let offset = 0;
labelItem.label.forEach(el => {
let elTextMetrics = ctx.measureText(el);
let elWidth = elTextMetrics.width;
if (labelItem.label.indexOf(el) === 0) {
ctx.font = fontStringMain || defaultFontString;
} else {
ctx.font = fontStringSubTitle || defaultFontString;
}
ctx.save();
ctx.fillStyle = color || Chart.defaults.color
ctx.fillText(el, (labelItem.translation[0] - elWidth / 2), labelItem.translation[1] + labelItem.textOffset + offset);
ctx.restore();
offset += elTextMetrics.fontBoundingBoxAscent + elTextMetrics.fontBoundingBoxDescent;
});
}
// Draw white box over old label
}
}]
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.js"></script>
</body>
I spent couple hours browsing the internet and searching for some solution how to capture desktop (or window) and send it to OpenCv VideoCapture so that I can do some computer vision magic on it.
After doing my research the only solution that I was able to think of is starting stream with desktopCapturer and passing the stream to opencv library.
I have this code:
const { desktopCapturer } = require('electron');
var cv = require('electron').remote.require('opencv4nodejs');
...some setup...
navigator.mediaDevices.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: source.id,
minWidth: 640,
maxWidth: 640,
minHeight: 320,
maxHeight: 320,
},
},
})
.then((stream) => {
console.log('stream ', stream);
const videoUrl = URL.createObjectURL(stream);
console.log('videoUrl', videoUrl);
const capturedVideo = new cv.VideoCapture(videoUrl);
console.log('captured video', capturedVideo);
})
.catch((error) => console.error(error));
But I get following error:
Following piece of code actually handles the conversion between browser desktop capturer and nodejs for opencv and other libraries:
}).then((stream) => {
const video = document.createElement('video');
video.srcObject = stream;
video.onloadedmetadata = () => {
video.play();
setInterval(() => {
const canvas = document.createElement('canvas');
canvas.getContext('2d').drawImage(video, 0, 0, 800, 800);
canvas.toBlob(blob => {
toBuffer(blob, function (err, buffer) {
if (err) throw err;
// do some magic with buffer
});
});
}, 40);
};
i want to select image from gallery ,crop it and save cropped image to gallery as a file.
i used camera native but i can't save it to my gallery again
const options: CameraOptions = {
quality: 100,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
//allowEdit: true
}
this.camera.getPicture(options).then((imageData) => {
this.base64Image = "data:image/JPEG;base64,"+imageData;
//this.path =this.base64Image.toDataURL;
console.log("path ",this.base64Image);
//resolve(this.base64Image);
}, (err) => {
console.log("error",err)
});
You need to save the file yourself using cordova-plugin-file. Here is some instruction on how to do so:
https://ourcodeworld.com/articles/read/150/how-to-create-an-image-file-from-a-base64-string-on-the-device-with-cordova
I'm generating a BarChart with Google's javascript visualization libraries. I would like to make the bars in the chart to be wider than they currently are, but I can't find anything in the documentation which shows how to configure the width of the bars of each data set.
Any help?
Had this same question, figured I'd post for posterity. The bar.groupWidth appears to be the way to set this.
https://developers.google.com/chart/interactive/docs/gallery/barchart
For example:
var options = {
title: "Density of Precious Metals, in g/cm^3",
width: 600,
height: 400,
bar: {groupWidth: "95%"},
legend: { position: "none" },
};
var chart = new google.visualization.BarChart(document.getElementById("barchart_values"));
chart.draw(view, options);
Try below format so the graph will have decently look, its not fixed but this solved our issue.
options: {
titlePosition: "none",
bar: { groupWidth: "50%" }
// ...
}
data.push([" ", "t1","t2","t3","t4"]); // headings
data.push([" ", 0, 0, 0, 0]); // dummy bar so graph will display good
// push you actual data here
data.push([" ", 0, 0, 0, 0]); // dummy bar so graph will display good