-
-
Notifications
You must be signed in to change notification settings - Fork 763
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add \n support for image.print #865
Comments
+1 from me. I added jimp to node-red via a contrib node node-red-contrib-image-tools |
Writing multiple line textThough I am late, I wrote a solution for this which can be used in your code. const breakTextToLines = (
text: string,
maxCharsPerLine: number,
minWordsPerLine: number
) => {
// Function takes text and breaks it to lines where every line is the closest to maxCharsPerLine as possible
// Line breaks only at ' ' so no words are cut
const words = text.split(" ");
let lines: string[] = [];
let charCount = 0;
let currLine = "";
for (const word of words) {
// every max amount of chars make a new line
if (charCount + word.length > maxCharsPerLine) {
lines.push(currLine);
currLine = "";
charCount = 0;
} else if (currLine !== "") {
// Don't add space at first
currLine += " ";
}
charCount += word.length;
currLine += word;
}
// Add last line that we didn't get to the end of it
// Optional, add to last line only if it has more than 2 words
if (currLine.split(" ").length < minWordsPerLine) {
lines.push(lines.pop() + " " + currLine);
} else {
lines.push(currLine);
}
if (lines.length === 0) {
// Which means text is shorter than MAX_CHARS_PER_LINE
lines.push(currLine);
}
return lines;
}; Add text-adding function: const addTextToImage = async (
image: Jimp,
text: string,
spaceBetweenLines: number,
font: any
) => {
// font isn't any but because this is typescript I got no option to get 'Font' type
const lines = breakTextToLines(text, Constants.MAX_CHARS_PER_LINE, 2);
let textWidth = Jimp.measureText(font, lines[0]);
const singleLineHeight = Jimp.measureTextHeight(font, 'a', textWidth); // Just to have the height of a line, could be any char
const allTextHeight = singleLineHeight * lines.length; // Used to center the whole text
image.print(
font,
// Centering:
Constants.IMAGE_SIZE / 2 - textWidth / 2,
Constants.IMAGE_SIZE / 2 - allTextHeight / 2,
lines[0],
textWidth,
singleLineHeight,
(err, image, { y }) => {
if (err) {
throw err;
}
for (let i = 1; i < lines.length; i++) {
// Add all lines, everytime drop lineHeight + spaceBetweenLines
textWidth = Jimp.measureText(font, lines[i]);
image.print(
font,
Constants.IMAGE_SIZE / 2 - textWidth / 2,
y + singleLineHeight * (i - 1) + spaceBetweenLines * i, // Formula explanation: i - 1 because at first we get the bottom of the line and then we just calculate the others (from the top so we need to add the whole line value)
lines[i],
textWidth,
singleLineHeight
);
}
}
);
}; Notice I am centering the text here but you can use it for other cases, just take |
hi, could you write example to using this function please? big thanks |
I also wrote a simple workaround to support newlines in texts. Works perfect for my left aligned texts. Basically it makes use of the auto wrapping feature. It adds just enough spaces to the text to force a newline on the location where it has to break. Tested in NodeJS. const Jimp = require('jimp');
const imageWidth = 1050;
const imageHeight = 330;
let text = 'First line \nsecond line \nlast line!';
new Jimp(imageWidth, imageHeight, '#FFFFFF', (err, image) => {
Jimp.loadFont(Jimp.FONT_SANS_64_BLACK).then(font => {
// Simulate newlines.
const texts = text.split('\n');
if (texts.length > 1) {
for (let i = 0; i < texts.length - 1; i++) {
let width = Jimp.measureText(font, texts[i] + '|');
while (width < imageWidth) {
texts[i] += ' ';
width = Jimp.measureText(font, texts[i] + '|');
}
}
text = texts.join('');
}
image.print(font, 0, 0, text, imageWidth, imageHeight);
image.write(__dirname + '/image-with-text.png');
});
}); Result: |
These all seem like great PRs |
I'm afraid I have to delve into the code and create a patch to solve this issue myself. 😬 |
Created a Pull Request to solve this issue. PR #1265 |
🚀 Issue was released in |
🚀 Issue was released in |
Thanks for accepting this improvement.
Would be an honor to be on the contributors list ;-)
https://www.linkedin.com/in/robjuurlink/
Rob Juurlink - Front End Expert B.V.
linkedin.com
… Op 6 feb 2023, om 07:31 heeft Andrew Lisowski ***@***.***> het volgende geschreven:
These all seem like great PRs
—
Reply to this email directly, view it on GitHub <#865 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAG2VNF37MGUR4CW5C6PWSLWWCLCPANCNFSM4LVKJTKA>.
You are receiving this because you commented.
|
Could you make an issue for me for that? Should be automatic |
Is your feature request related to a problem? Please describe.
I've been using Jimp to render text since I first started JS. It works extremely well most of the time, but I've always been quite bothered by the fact that the \n character simply leaves a small space instead of starting a new line. Considering the
maxWidth
parameter splits text across multiple lines, I'm not sure why it would be so difficult to implement.Describe the solution you'd like
Simply allowing \n to be used to start new lines. It can be bypassed by simply replacing all newlines in the string with spaces. Also, perhaps a
lineHeight
parameter can be passed into the settings to customize how big of a gap to leave between lines.Describe alternatives you've considered
For now I've been using a simple function I wrote to draw multiline text, in place of
image.print
. However, I really don't believe this should be necessary.The text was updated successfully, but these errors were encountered: