print.test.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /* eslint key-spacing: ["error", { "align": "value" }] */
  2. import { Jimp, getTestDir, hasOwnProp } from '@jimp/test-utils';
  3. import configure from '@jimp/custom';
  4. import blit from '@jimp/plugin-blit';
  5. import print from '../src';
  6. const jimp = configure({ plugins: [print, blit] }, Jimp);
  7. async function createTextImage(
  8. width,
  9. height,
  10. font,
  11. { x = 0, y = 0, text, maxWidth, maxHeight }
  12. ) {
  13. const loadedFont = await jimp.loadFont(font);
  14. const image = await Jimp.create(width, height, 0xffffffff);
  15. return image.print(loadedFont, x, y, text, maxWidth, maxHeight);
  16. }
  17. describe('Write text over image', function() {
  18. this.timeout(30000);
  19. const fontDefs = {
  20. SANS_8_BLACK: { w: 28, h: 28, bg: 0xffffffff },
  21. SANS_16_BLACK: { w: 54, h: 54, bg: 0xffffffff },
  22. SANS_32_BLACK: { w: 114, h: 114, bg: 0xffffffff },
  23. SANS_64_BLACK: { w: 220, h: 220, bg: 0xffffffff },
  24. SANS_8_WHITE: { w: 28, h: 28, bg: 0x000000ff },
  25. SANS_16_WHITE: { w: 54, h: 54, bg: 0x000000ff },
  26. SANS_32_WHITE: { w: 114, h: 114, bg: 0x000000ff },
  27. SANS_64_WHITE: { w: 220, h: 220, bg: 0x000000ff }
  28. };
  29. for (const fontName in fontDefs)
  30. if (hasOwnProp(fontDefs, fontName))
  31. ((fontName, conf) => {
  32. it('Jimp preset ' + fontName + ' bitmap font', async () => {
  33. const font = await jimp.loadFont(Jimp['FONT_' + fontName]);
  34. const expected =
  35. getTestDir(__dirname) + '/images/' + fontName + '.png';
  36. const expectedImg = await Jimp.read(expected);
  37. const image = await Jimp.create(conf.w, conf.h, conf.bg);
  38. image
  39. .print(font, 0, 0, 'This is only a test.', image.bitmap.width)
  40. .bitmap.data.should.be.deepEqual(expectedImg.bitmap.data);
  41. });
  42. })(fontName, fontDefs[fontName]);
  43. it('Jimp preset SANS_16_BLACK bitmap font positioned', async () => {
  44. const font = await jimp.loadFont(Jimp.FONT_SANS_16_BLACK);
  45. const expected =
  46. getTestDir(__dirname) + '/images/SANS_16_BLACK-positioned.png';
  47. const expectedImg = await Jimp.read(expected);
  48. const image = await Jimp.create('300', '100', 0xff8800ff);
  49. image
  50. .print(font, 150, 50, 'This is only a test.', 100)
  51. .bitmap.data.should.be.deepEqual(expectedImg.bitmap.data);
  52. });
  53. it('Jimp loads font from URL', async () => {
  54. const font = await Jimp.loadFont(
  55. 'https://raw.githubusercontent.com/oliver-moran/jimp/master/packages/plugin-print/fonts/open-sans/open-sans-16-black/open-sans-16-black.fnt'
  56. );
  57. const expected =
  58. getTestDir(__dirname) + '/images/SANS_16_BLACK-positioned.png';
  59. const expectedImg = await Jimp.read(expected);
  60. const image = await Jimp.create('300', '100', 0xff8800ff);
  61. image
  62. .print(font, 150, 50, 'This is only a test.', 100)
  63. .bitmap.data.should.be.deepEqual(expectedImg.bitmap.data);
  64. });
  65. it('Jimp renders ? for unknown characters', async () => {
  66. const font = await jimp.loadFont(Jimp.FONT_SANS_16_BLACK);
  67. const expected = getTestDir(__dirname) + '/images/unknown-char-test.png';
  68. const expectedImg = await Jimp.read(expected);
  69. const image = await Jimp.read('300', '100', 0xff8800ff);
  70. image
  71. .print(font, 0, 0, 'ツ ツ ツ', 100)
  72. .bitmap.data.should.be.deepEqual(expectedImg.bitmap.data);
  73. });
  74. it('Jimp can print numbers too', async () => {
  75. const font = await Jimp.loadFont(Jimp.FONT_SANS_16_BLACK);
  76. const expected = getTestDir(__dirname) + '/images/print-number.png';
  77. const expectedImg = await Jimp.read(expected);
  78. const image = await Jimp.read('300', '100', 0xff8800ff);
  79. image
  80. .print(font, 0, 0, 12345678, 100)
  81. .bitmap.data.should.be.deepEqual(expectedImg.bitmap.data);
  82. });
  83. it('left-align text by default', async () => {
  84. const expectedImage = await Jimp.read(
  85. getTestDir(__dirname) + '/images/left-aligned.png'
  86. );
  87. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  88. text: 'This is only a test.',
  89. maxWidth: 100
  90. });
  91. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  92. });
  93. it('left-align text by default when passing object', async () => {
  94. const expectedImage = await Jimp.read(
  95. getTestDir(__dirname) + '/images/left-aligned.png'
  96. );
  97. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  98. text: { text: 'This is only a test.' },
  99. maxWidth: 100
  100. });
  101. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  102. });
  103. it('left-align text when passing object with alignmentX', async () => {
  104. const expectedImage = await Jimp.read(
  105. getTestDir(__dirname) + '/images/left-aligned.png'
  106. );
  107. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  108. text: {
  109. text: 'This is only a test.',
  110. alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT
  111. },
  112. maxWidth: 100
  113. });
  114. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  115. });
  116. it('center-align text when passing object with alignmentX', async () => {
  117. const expectedImage = await Jimp.read(
  118. getTestDir(__dirname) + '/images/center-aligned.png'
  119. );
  120. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  121. text: {
  122. text: 'This is only a test.',
  123. alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER
  124. },
  125. maxWidth: 100
  126. });
  127. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  128. });
  129. it('right-align text when passing object with alignmentX', async () => {
  130. const expectedImage = await Jimp.read(
  131. getTestDir(__dirname) + '/images/right-aligned.png'
  132. );
  133. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  134. text: {
  135. text: 'This is only a test.',
  136. alignmentX: Jimp.HORIZONTAL_ALIGN_RIGHT
  137. },
  138. maxWidth: 100
  139. });
  140. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  141. });
  142. it('middle-align text when passing object with alignmentY', async () => {
  143. const expectedImage = await Jimp.read(
  144. getTestDir(__dirname) + '/images/middle-aligned.png'
  145. );
  146. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  147. text: {
  148. text: 'This is only a test.',
  149. alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
  150. },
  151. maxWidth: 100,
  152. maxHeight: 240
  153. });
  154. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  155. });
  156. it('middle-align text when passing object with alignmentY can offset y', async () => {
  157. const expectedImage = await Jimp.read(
  158. getTestDir(__dirname) + '/images/middle-aligned-y.png'
  159. );
  160. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  161. y: 50,
  162. text: {
  163. text: 'This is only a test.',
  164. alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
  165. },
  166. maxWidth: 100,
  167. maxHeight: 240
  168. });
  169. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  170. });
  171. it('bottom-align text when passing object with alignmentY', async () => {
  172. const expectedImage = await Jimp.read(
  173. getTestDir(__dirname) + '/images/bottom-aligned.png'
  174. );
  175. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  176. text: {
  177. text: 'This is only a test.',
  178. alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM
  179. },
  180. maxWidth: 100,
  181. maxHeight: 240
  182. });
  183. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  184. });
  185. it('bottom-align text when passing object with alignmentY offset y', async () => {
  186. const expectedImage = await Jimp.read(
  187. getTestDir(__dirname) + '/images/bottom-aligned-y.png'
  188. );
  189. const textImage = await createTextImage(320, 240, Jimp.FONT_SANS_16_BLACK, {
  190. y: 100,
  191. text: {
  192. text: 'This is only a test.',
  193. alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM
  194. },
  195. maxWidth: 100,
  196. maxHeight: 100
  197. });
  198. expectedImage.bitmap.data.should.be.deepEqual(textImage.bitmap.data);
  199. });
  200. it('exposes print y position in cb', async () => {
  201. const expectedImage = await Jimp.read(
  202. getTestDir(__dirname) + '/images/spacing.png'
  203. );
  204. const loadedFont = await jimp.loadFont(Jimp.FONT_SANS_16_BLACK);
  205. const image = await Jimp.create(500, 500, 0xffffffff);
  206. image.print(
  207. loadedFont,
  208. 0,
  209. 0,
  210. 'One two three four fix six seven eight nine ten eleven twelve',
  211. 250,
  212. (err, image, { x, y }) => {
  213. image.print(
  214. loadedFont,
  215. x,
  216. y + 50,
  217. 'thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty',
  218. 250
  219. );
  220. }
  221. );
  222. expectedImage.bitmap.data.should.be.deepEqual(image.bitmap.data);
  223. });
  224. });