7

I need to generate 50x50 png icons, I do it as following:

  1. Create a tikz file with a radius 25 circle.
\documentclass[border=0pt]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \draw(0,0) circle (25);
\end{tikzpicture}
\end{document}
  1. Run below command to convert pdf to png file:

    convert -density 2 test.pdf test.png

  2. Check the png file size: It's 39x39 pixels

Looks like this way image size is smaller and quality is bad! I wish image is 50x50 and line width is 1 pixel. What's the correct way to get right pixel size and good quality?

enter image description here

2
  • Did you try with the resize option? For example: convert test.pdf -resize 50x50 test.jpg?
    – Ivan
    Mar 18, 2021 at 22:20
  • 2
    Well, a circle with a radius of 25 cm fits into a square of 50 × 50 cm. If you rasterize this with 2 dots per inch (= dpi = px/in), you get 50 cm * 2 px/in * 0.393701 in/cm = approx. 39 pixels ... this is somehow to be expected, isn't it? Mar 18, 2021 at 22:23

3 Answers 3

6

TikZ uses centimeters as default unit, but rasterizing uses dots per inch. So we either need to do some math or we need to tell TikZ to use inch.

A circle with a radius of 25 cm fits into a square of 50 × 50 cm. If you rasterize this with 2 dots per inch (= dpi = px/in), you get 50 cm × 2 px/in × 0.393701 in/cm = approx. 39 pixels. This is exactly what you got.

Since rasterizing using dpi (which is the default rasterizing unit) means converting inch to pixels, you could just use inch as basic unit in your TikZ picture (for example by drawing a circle with a radius of 25 inch using \draw(0,0) circle (25in);) and than rasterize this using 1 dpi.

There is just one problem here: in TikZ, borders always expand to both sides of a path, which is why the border of the circle will be clipped halfways. So, you actually need to draw it half an inch smaller and make sure that it won't be clipped.

Thus, the following rasterized using 1 dpi (probably using convert -density 1 filename.pdf filename.png) should get you what you want (I did not try to rasterize it using your method):

\documentclass[border=0pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
    \fill[transparent] (-25in,-25in) rectangle (25in,25in);
    \draw[line width=1in] (0,0) circle (24.5in); 
\end{tikzpicture}
\end{document}

Result: a square of 50 × 50 pixels with a circle having a border of 1 pixel.

enter image description here

4

In this example I use ghostscript to rip the pdf output into a rastered png at 900 dpi, with 900x900 pixels. You can specify any dpi you want with -r and the image size with -g.

gs -sDEVICE=pngalpha -dPDFFitPage -r900 -g900x900 -o test.png test.pdf

rip

\documentclass[border=0pt]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \draw(0,0) circle (25);
\end{tikzpicture}
\end{document}
1
  • Thanks, large dpi looks fine, but if use lower dpi (50x50 in tis case), image quality is bad! how can we get good image quality even if with low dpi?
    – lucky1928
    Mar 19, 2021 at 23:52
1

I would like to use python to draw small icons:

#!/usr/bin/env python3
from skimage import draw
import numpy as np
import cv2

def main():
    circle()
    return

def circle():
    r = 25
    arr = np.zeros((2*r, 2*r),dtype=np.uint8)
    arr.fill(255)# white
    rr, cc = draw.circle_perimeter(r, r, radius=r-1, shape=arr.shape)
    arr[rr, cc] = 0 #black
    cv2.imwrite("logo.png",arr)
    winname = "test"
    cv2.imshow(winname,arr)
    cv2.waitKey(0)
    return

if __name__ == "__main__":
    main()

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .