You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

242 lines
6.6 KiB

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # img2txt image to text converter
  5. # Copyright (c) 2010 Alex Foulon <alxf@lavabit.com>
  6. #
  7. # This file is a Python port of "src/img2txt.c"
  8. # which is:
  9. # Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
  10. # 2007 Jean-Yves Lamoureux <jylam@lnxscene.org>
  11. # All Rights Reserverd
  12. #
  13. # This library is free software. It comes without any warranty, to
  14. # the extent permitted by applicable law. You can redistribute it
  15. # and/or modify it under the terms of the Do What The Fuck You Want
  16. # To Public License, Version 2, as published by Sam Hocevar. See
  17. # http://sam.zoy.org/wtfpl/COPYING for more details.
  18. #
  19. import getopt
  20. import os
  21. import sys
  22. import caca
  23. from caca.canvas import Canvas, CanvasError
  24. from caca.dither import Dither, DitherError
  25. RMASK = 0x00ff0000
  26. GMASK = 0x0000ff00
  27. BMASK = 0x000000ff
  28. AMASK = 0xff000000
  29. BPP = 32
  30. DEPTH = 4
  31. HELP_MSG = """\
  32. Usage: %s [OPTIONS]... <IMAGE>
  33. Convert IMAGE to any text based available format.
  34. Example: %s -w 80 -f ansi ./caca.png
  35. Options:
  36. -h, --help This help
  37. -v, --version Version of the program
  38. -W, --width=WIDTH Width of resulting image
  39. -H, --height=HEIGHT Height of resulting image
  40. -x, --font-width=WIDTH Width of output font
  41. -y, --font-height=HEIGHT Height of output font
  42. -b, --brightness=BRIGHTNESS Brightness of resulting image
  43. -c, --contrast=CONTRAST Contrast of resulting image
  44. -g, --gamma=GAMMA Gamma of resulting image
  45. -d, --dither=DITHER Dithering algorithm to use
  46. -f, --format=FORMAT Format of the resulting image
  47. -C, --charset=CHARSET Charset of the resulting image
  48. DITHER list:
  49. - none: no dithering
  50. - ordered2: 2x2 ordered dithering
  51. - ordered4: 4x4 ordered dithering
  52. - ordered8: 8x8 orederd dithering
  53. - random: random dithering
  54. - fstein: Floyd-Steinberg dithering
  55. FORMAT list:
  56. - caca: native libcaca format
  57. - ansi: ANSI
  58. - utf8: UTF-8 with ANSI escape codes
  59. - utf8cr: UTF-8 with ANSI escape codes and MS-DOS \\r
  60. - html: HTML
  61. - html3: backwards-compatible HTML
  62. - bbfr: BBCode (French)
  63. - irc: IRC with mIRC colours
  64. - ps: PostScript document
  65. - svg: SVG vector image
  66. - tga: TGA image
  67. - troff: troff source
  68. CHARSET list:
  69. - ascii: use only ascii character
  70. - shades: use unicode character
  71. - blocks: use unicode quarter-cell combinations
  72. """ % (os.path.basename(sys.argv[0]), os.path.basename(sys.argv[0]))
  73. VERSION_MSG="""\
  74. img2txt Copyright 2006-2007 Sam Hocevar and Jean-Yves Lamoureux
  75. Copyright 2010 Alex Foulon
  76. Internet: <sam@hocevar.net> <jylam@lnxscene.org>
  77. <alxf@lavabit.com> version: %s
  78. img2txt, along with its documentation, may be freely copied and distributed.
  79. The latest version of img2txt is available from the web site,
  80. http://caca.zoy.org/wiki/libcaca in the libcaca package.
  81. """ % caca.get_version()
  82. def main():
  83. """ Main script function.
  84. """
  85. #init options vars
  86. width = None
  87. height = None
  88. font_width = 6
  89. font_height = 10
  90. brightness = None
  91. contrast = None
  92. gamma = None
  93. ditalgo = None
  94. exformat = "ansi"
  95. charset = None
  96. #define long and short options
  97. shortopts = "hvW:H:x:y:b:c:g:d:f:C:"
  98. longopts = [
  99. "help",
  100. "version",
  101. "width=",
  102. "height=",
  103. "font-width=",
  104. "font-height=",
  105. "brightness=",
  106. "contrast=",
  107. "gamma=",
  108. "dither=",
  109. "format=",
  110. "charset=",
  111. ]
  112. #parse command line
  113. try:
  114. opts, args = getopt.getopt(sys.argv[1:], shortopts, longopts)
  115. except getopt.GetoptError, err:
  116. sys.stderr.write("%s\n" % str(err))
  117. sys.exit(127)
  118. for o, a in opts:
  119. if o in ('-h', '--help'):
  120. sys.stdout.write(HELP_MSG)
  121. sys.exit(0)
  122. elif o in ('-v', '--version'):
  123. sys.stdout.write("%s\n" % VERSION_MSG)
  124. sys.exit(0)
  125. elif o in ('-W', '--width'):
  126. width = int(a)
  127. elif o in ('-H', '--height'):
  128. height = int(a)
  129. elif o in ('-x', '--font-width'):
  130. font_width = int(a)
  131. elif o in ('-y', '--font-height'):
  132. font_height = int(a)
  133. elif o in ('-b', '--brightness'):
  134. brightness = float(a)
  135. elif o in ('-c', '--contrast'):
  136. contrast = float(a)
  137. elif o in ('-g', '--gamma'):
  138. gamma = float(a)
  139. elif o in ('-d', '--dither'):
  140. ditalgo = a
  141. elif o in ('-f', '--format'):
  142. exformat = a
  143. elif o in ('-C', '--charset'):
  144. charset = a
  145. if not args:
  146. sys.stderr.write("%s: Missing argument...\n" % os.path.basename(sys.argv[0]))
  147. sys.exit(127)
  148. else:
  149. try:
  150. img = Image.open(args[0])
  151. img.load()
  152. except IOError, err:
  153. sys.stderr.write("%s\n" % err)
  154. sys.exit(127)
  155. if not width and not height:
  156. width = 60
  157. height = width * img.size[1] * font_width / img.size[0] / font_height
  158. elif width and not height:
  159. height = width * img.size[1] * font_width / img.size[0] / font_height
  160. elif not width and height:
  161. width = height * img.size[0] * font_height / img.size[1] / font_width
  162. #init canvas
  163. try:
  164. cv = Canvas(width, height)
  165. except CanvasError, err:
  166. sys.stderr.write("%s\n" % err)
  167. sys.exit(127)
  168. cv.set_color_ansi(caca.COLOR_DEFAULT, caca.COLOR_TRANSPARENT)
  169. #init dither
  170. try:
  171. #convert rgb to rgba
  172. if img.mode == 'RGB':
  173. img = img.convert('RGBA')
  174. #reorder rgba
  175. if img.mode == 'RGBA':
  176. r, g, b, a = img.split()
  177. img = Image.merge("RGBA", (b, g, r, a))
  178. dit = Dither(BPP, img.size[0], img.size[1], DEPTH * img.size[0],
  179. RMASK, GMASK, BMASK, AMASK)
  180. except DitherError, err:
  181. sys.stderr.write("%s\n" % err)
  182. sys.exit(127)
  183. #set dither algorithm
  184. if ditalgo:
  185. dit.set_algorithm(ditalgo)
  186. #set brightness
  187. if brightness:
  188. dit.set_brightness(brightness)
  189. #set gamma
  190. if gamma:
  191. dit.set_gamma(gamma)
  192. #set contrast
  193. if contrast:
  194. dit.set_contrast(contrast)
  195. #set charset
  196. if charset:
  197. dit.set_charset(charset)
  198. #create dither
  199. dit.bitmap(cv, 0, 0, width, height, img.tostring())
  200. #print export to screen
  201. sys.stdout.write("%s" % cv.export_to_memory(exformat))
  202. if __name__ == "__main__":
  203. #Import PIL package
  204. try:
  205. from PIL import Image
  206. except ImportError, err:
  207. sys.stderr.write("You need to install PIL module !\n")
  208. sys.exit(2)
  209. main()