Split image file in two separate image - javascript

I have on my server an image file with an height of 50 000px.
I want to save 2 files of 25 000px each (first and second part of the original image)
Any suggestions about how to do that ?
Thanks

The sharp image package might be useful for this scenario. More specifically the extract method.
I've added a link to the documentation but here's a possible implementation to split up the image.
const sharp = require("sharp");
const originalFilename = "image.jpg";
const image = sharp(originalFilename);
// this is just a placeholder
const imageWidth = 500;
image
.extract({ left: 0, top: 0, width: imageWidth, height: 25000 })
.toFile("top.jpg", function(err) {
// Save the top of the image to a file named "top.jpg"
});
image
.extract({ left: 0, top: 25000, width: imageWidth, height: 25000 })
.toFile("bottom.jpg", function(err) {
// Save the bottom of the image to a file named "bottom.jpg"
});
I'm assuming you can reuse the original sharp image object to call the extract function twice. If not you might need to call the sharp constructor again.

Related

jsPDF.html method doesn't recognize the image quality option

Method jsPDF.html() has an option to set the image quality (HTMLOptionImage) but this does not seem to affect the image quality or inevitably the document size at all.
My goal is to get the PDF document size down to a reasonable level, but anytime I add images, it blows it up way larger than it needs to be. Like even a 50kb image file on the document turns it into a 1 MB PDF.
It also seems compress doesn't really affect it, the PDF is the same size either way.
Example code using an external image (may have to run this on your local).
package.json running "react": "^17.0.2", and "jspdf": "^2.3.1",
import { jsPDF } from "jspdf";
const stackoverflow = () => {
function downloadMe() {
const ele = document.querySelector('#stackoverflowexample');
const pdf = new jsPDF({
orientation: 'p',
unit: 'px',
format: 'letter',
compress: true,
putOnlyUsedFonts: true,
hotfixes: ['px_scaling'] // an array of hotfix strings to enable
});
pdf.html(ele, {
image: { quality: 10, type: "jpeg" },
x: 10,
y: 10,
callback: function (doc) {
doc.save(); // File size is huge even though images are small kb
// attachment = doc.output('datauristring');
},
});
}
return (
<div id="stackoverflowexample">
<h1>PDF</h1>
<button onClick={downloadMe}>Download Button</button>
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Borobudur-Temple-Park_Elephant-cage-01.jpg/320px-Borobudur-Temple-Park_Elephant-cage-01.jpg" />
<p>Image makes PDF larger than it should have to be</p>
</div>)
}
export default stackoverflow;
So I can solve this file size issue by selectively removing and re-adding those image elements with an addImage but it doesn't address the underlying problem that the .html method is blowing up the img element data sizes.
html2canvas: {
onclone: (doc) => {
let target = doc.querySelector("#stackoverflowexample");
let images = target.querySelectorAll("img");
let targetRect = target.getBoundingClientRect();
images.forEach((img) => {
let rect = img.getBoundingClientRect();
pdf.addImage(img, "JPEG", targetRect.x - rect.x, targetRect.y - rect.y, rect.width, rect.height);
img.remove();
});
}
The image object has a multiplier property, try using that, it will effect the quality of the image and this would result in a greater or lesser file size depending upon what value you set of multiplier
image: { quality: 10, type: "jpeg", multiplier: .5 }

Canvas to PDF, HTML, Konva.js

I am working about draggable objects on Konva stage. I want to the canvas object layer turn to PDF. I use toDataURL. Like this;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
id: 'stage',
});
var grid_layer = new Konva.Layer();
var object_layer = new Konva.Layer();
stage.add(grid_layer);
stage.add(object_layer);
function updateScreen() {
object_layer.batchDraw()
}
function downloadURI(uri, name) {
var link = document.createElement('a');
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
}
document.getElementById('save').addEventListener(
'click',
function() {
var dataURL = stage.toDataURL({ pixelRatio: 3 });
downloadURI(dataURL, 'stage.png');
},
false
);
Save button work without objects and save canvas image. But when i run the code with objects on stage, the page reloads and the button doesn't work. doesn't save canvas image
I would strongly recommend to doing it like shown in the Konva Wiki.
// Code form KonvaJS wiki
var pdf = new jsPDF('l', 'px', [stage.width(), stage.height()]);
pdf.setTextColor('#000000');
// first add texts
stage.find('Text').forEach((text) => {
const size = text.fontSize() / 0.75; // convert pixels to points
pdf.setFontSize(size);
pdf.text(text.text(), text.x(), text.y(), {
baseline: 'top',
angle: -text.getAbsoluteRotation(),
});
});
// then put image on top of texts (so texts are not visible)
pdf.addImage(
stage.toDataURL({ pixelRatio: 2 }),
0,
0,
stage.width(),
stage.height()
);
pdf.save('canvas.pdf');
This should add all text and other objects to a pdf.
From the comments, I can conclude that you don't host the images using the server you use for the konva stuff. You can't access the images from your website as they are not from the same origin. This helps secure the files on your computer from the access of websites like yours. So you would have to move the images to the server and access them from there.

Dynamically change background images in React from local folder

I've been trying to load background images dynamically on my React app, but it only works when I link to my Google drive. I want to do this locally, and I've pasted the images on the immediate directory. But it still won't load on my app.
I have 21 images from 0-20 all png format in src folder
var bgp = Math.floor(Math.random() * 20);
this.setState({
chrome: color,
photo: bgp,
quote: randomQuote.quote,
author: randomQuote.name
})
render() {
var bodyP = {
backgroundImage: `url(${onUse}.png)`,
transition: 'all linear 2.5s',
height: '100vh',
width: '100vw',
}
return ( <div id = "wrapper" onLoad = {this.getQuote} style = {bodyP} >
</div>
)
if it worked fine with goggle drive before then I'm pretty sure this is a problem with how you've written your directory path.
try creating an and write your path leading to one of these pictures if the image didn't render, then keep trying to find the right way to write your path or take a look at some documentation until u see the image render, after that, u can use the right directory path in your code.
hope this works for u.
I've figured it out. I moved the photo folder to the public folder and then used the (process.env.PUBLIC_URL) file path description to the public path as explained by https://create-react-app.dev/docs/using-the-public-folder/ and navigated to the photo folder. So my code looks like:
getPhoto() {
var bgp = Math.floor(Math.random() * 20);
this.setState({
photo: bgp,
})
}
var onUse = process.env.PUBLIC_URL + "/Quote-photos/"+ this.state.photo + '.png';
var bodyP = {backgroundImage: `url(${onUse})`,
transition: 'all linear 2.5s',
height: '100vh',
width: '100vw'}

CropperJS creating new images on page instead of cropping the specified image

Using cropper js to attempt to crop an img on the page, however,
it's actually appending 2 more of the same images on the page that I can "scroll" to change their aspect ratio.
const cropper = new Cropper(image, {
aspectRatio: 16 / 9,
crop(event) {
console.log(event.detail.x);
console.log(event.detail.y);
console.log(event.detail.width);
console.log(event.detail.height);
console.log(event.detail.rotate);
console.log(event.detail.scaleX);
console.log(event.detail.scaleY);
}
});
I also tried to do this to set the crop sizes;
viewMode: 1,
setData() {
x: dimensions.left;
y: dimensions.top;
width: dimensions.width;
height: dimensions.height;
}
However, it's proving to be difficult. Am I missing something?
Switched to using the Jimp library. Was much easier to figure out how to crop using that.

<img/> tag width and height not correct when getting it from $('img).width()/height()

I am currently trying to get RGB data for a texture image, while displaying a preview of the texture to the user.
The user drops an image file into the form, and it should show the preview of the image, while drawing the image to an canvas to get the RGB values for each pixel:
handleTextureImageDrop = (e) ->
e.stopPropagation()
e.preventDefault()
if e.dataTransfer.files.length >= 1
file = e.dataTransfer.files[0]
if file
reader = new FileReader()
reader.onload = (loadEvent) ->
img = $ '<img/>'
img.attr
src: loadEvent.target.result
$(e.target).html img
reader.onloadend = (loadendEvent) ->
img = $(e.target).children 'img'
width = img.width()
height = img.height()
canvas = $ '<canvas/>',
width: width
height: height
$('#wrapper').append canvas
context = $('canvas').get(0).getContext '2d'
context.drawImage img.get(0), 0, 0
rgb = (for x in [0...width]
for y in [0...height]
context.getImageData(x, y, 1, 1).data)
canvas.remove()
TEXTURE_FILES.push
image: file.name
rgb: rgb
reader.readAsDataURL file
As it stands it works about 50% of the time, but the rest of the time width and height are set to 0, so the iteration across the pixel data never happens.
This would suggest to me that there is some sort of race condition happening where the image hasn't loaded into the <img/> tag yet.
Is that what is happening? Or am I missing something silly and obvious?
Any help would be much appreciated.
You will get correct width and height only after the image has been loaded. Usually $(img).load is used for this.
$(img).load(function(e){
var w = $(img).width();
var h = $(img).height();
});
$(img).attr("src", "http://....");
I am not familiar with coffeescript, so I am not able to understand whether you are doing this in your current code. If not please try it.

Categories