Loading imgutils/ascii/drawing.py +56 −50 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ __all__ = [ def ascii_drawing(img: ImageTyping, max_width: Optional[int] = ..., max_height: Optional[int] = ..., resample=Image.BILINEAR, levels: str = "@%#*+=-:. "): resample=Image.BILINEAR, levels: str = "@%#*+=-:. ", aspect: float = 1.8): """ Generate ASCII art drawing based on the given image. Loading @@ -30,6 +30,10 @@ def ascii_drawing(img: ImageTyping, max_width: Optional[int] = ..., max_height: :type resample: int :param levels: The characters used to represent different intensity levels in the ASCII art. :type levels: str :param aspect: Proportional correction for ASCII art output, which should approximate the aspect ratio of ASCII characters on your terminal. This value ensures that the aspect ratio of the output ASCII art is as close as possible to the original image. The default value is `1.8`. :type aspect: float :return: The ASCII art representation of the image. :rtype: str Loading @@ -39,57 +43,58 @@ def ascii_drawing(img: ImageTyping, max_width: Optional[int] = ..., max_height: .. image:: ascii_drawing_demo.plot.py.svg :align: center >>> from imgutils.ascii import ascii_drawing [50/1847] >>> from imgutils.ascii import ascii_drawing >>> >>> print(ascii_drawing('jerry.png')) :+- . .===.- ==-=:=: .:: .-*+++-:+. :+++==. .-++***+++: -+==-::= .+*++======:.====-:::-: .=+==--===---====+:::::-= .+*+=-==+=+=-==-=+-::::::= ++===-=++-==----+-:::::::+ :*++=--=++==----=+::::::::= -+=-=-==..=-----=-:::::::-= -+:.=-=: :=-----=-:-:::::=- :+ :=== ==-----==-+:::::+. .= --=: .=-------===::::-+ .+---=- -=-------==:::::+: .:==+===+=.---------=:::::== =++:=-=::-===-----=-::::-+. ..+++.=+- .=++++===-=::::-+. :+=... .:+==--=====:::==. =+: =+===--=+--==: ==... .=+++==+-::. . :::. .-==+**+**++=-..-- .:.--+++*+==--====++++: :=======-----------==--... .===--=-----------------====: =====--=-----=========-----=+. .+-+-=:.-=--=+==-:::+=-==---==- -+-+-:...==-=+: :=-===-==+: ==-=++=:..==--==-: :=+- -=- ==----==--:==---=++-. :+= ==------====+==---=++: ++. .+==-------==:==----=*+=+. .-==+===--=-..-=----=*+- :-:=-==-...==----=* -:====-...:=-----+- .=-:.-:....=-----=+ :=:.......=------+- .++-:....-=------=+ .+==++===++=-------=- +=----==++--==------= .+-----==. .-==----=: .+----== .-==---=. -=---=: :==--===--: .-+=---= -=----==== -===---=: :=----==+ :=----=+: -==---=- -=+++*- :++++= :=++: : =+===+: =: ++----== -*: ..:.. .::=*++++==+. =+-. :=++++++==: .:-*++++****+==+++=. .-++=====--::== .=*++++++++++++===+=. .=++==++=:::::::== :=+++====----===--=---==-=+=-=++-::::::::::*: .-***+=---==-=+++++=----=====--=*=::::::::::::*= :***+=++=---+=++=--=+----=-----+*-:::::::::::::++ .**+*+=-==---=+***=-==---------+*-::::::::::::::*+ =*==*===----=+=:.:+-=---------=*-:::::::::::::::#- ++=+: -=---=+- :+-----------++:::::::::::::::=#. +++. ==--=*- ++-----------=+:::-+::::::::::*+ -+= .+---+- -+=------------====+=:::::::::+#. .++. ==---+. :+=--------------==+=:::::::::=#- .:=*+.=---=*+ .==--------------=+=-:::::::::=#- .=++++==+======*= .=====------------==::::::::::+*- .#+==+:.=---+:..::-+++======-------=+:::::::::-*+: .....:**==+. :++=-. ..:++=======+=====-=+-:::::::-++- :*+=+. .. ..::*+====------====+=:::::-=+=: .=++=. . =*+==++===---=++=---===-: :=+=. -: .:=+++++++===*+-::::.. ... :::::. ..-=====+****+++*****+++=-::..-==-. .::.:--=++++++*#+==-==------======++++++-.. :============-----------------------====--:.. .. -+==+==--==--------------------------------=======+=: -*=-=+-+-==-===-----------===============----------==+- :*=--++.===:..-==-----==++++===-----=*++---=+=------===+- *+---++..::....:=+=--===+=. -==-.:+====-==-=++=- -#=--=++=+==-:....-+=-----===-:.. .===++=-. :=+==+. =#=------======-::::===------==++++=:. .-+==: ... -#=------------=====--=+==-------==++*+: -*=*: +*==--------------====+=-===--------==**=-++=*- -=+++========------=+=:..:===---------=*#+=+= ..:::+=::===---==+:.....:==---------=+#+. .=-..====++=+=.......==----------+#- ==:-===--=+-........+=----------+#- -+=:....::.........+=-----------=*- .+*=:............-+-------------=*: .=+=+++=-:::..::-=+=--------------=*: .=+=----==++++++++*++===-------------=+. ++=----------=+++=-:..:-=+==----------=+. .#=---------=++-. .-=+==--------==. ++---------+- .-=+==------==:. =+=-------+: .-=+=-----=========-. :-=++==-----=+- .-==----------===++ :++=====------=+. -+=--------==+++ -+=--------==++ :++==-------=+. .-=++++++**+-. :=+++++++=-. """ if max_width is ... or max_height is ...: terminal = shutil.get_terminal_size(fallback=(80, 40)) Loading @@ -97,6 +102,7 @@ def ascii_drawing(img: ImageTyping, max_width: Optional[int] = ..., max_height: max_height = terminal.lines - 5 if max_height is ... else max_height img = load_image(img, force_background='white', mode='RGB') img = img.resize((int(img.width * aspect), img.height)) if (max_width is not None and img.width > max_width) or \ (max_height is not None and img.height > max_height): r1 = max_width / img.width if max_width else +math.inf Loading test/ascii/test_drawing.py +52 −51 Original line number Diff line number Diff line Loading @@ -28,61 +28,62 @@ class TestAsciiDrawing: text_aligner.assert_equal( ascii_drawing(jerry), """ .=-. ==-:. .-++=:=. .-==- =++*++=: .===-:- .-+=======-===:::-. :++======-====::::-: ++===++==---=:::::-: :++=-=--=---=-:::::-: :=.-== :=---=-:::::=. .-.==. =----===::::= .=:==..=-----==:::=: .-=+==+:-=-----=::::= .+=-=-::=====-=-:::=. .+=.-:.-+======::-=. :+: :+===-=---: :-.. :===++--:. .. ...:-++++===++===: -=====-------==--... .=====------===----==- ====::=--====-=+-=--==: .+==::.-===- .=-=--==. :+-===::-=-==-: .== :: .+----=====--===::+: =====--==--=--=+++: ::--=-==..-=--=*- --===..:=---== :-:::...-----+: -=:....=----== .==+=--==-----=: ==--===-:==----- .=---=- :==--=. ==--= -=--=-:: .===-=. .==-==== :=---=- .==--== -==++. .====: -==: : ==--=.-- . .:=+++++-.==. .-=====-. .-*+++***+++==. :=+===-:::=: .:=++============-:===+=-::::::+ .=+++=--==+==+=---===-=+-::::::::+: :*++===--=+++===------=+::::::::::+: ++++==--==-.-==------=+:::::::::::*. +=- -=-=+: ==-------==::-:::::::=+ =+ =--=: :+--------====+:::::::*: -+::=--+. .==---------==+-::::::+- ..:--=+=-===*: -==---------=-:::::::+= .*++=.====:::-++======---==::::::=+: =+== .-:...:++==========+::::-==- -++. . ..=++====---=+------. .-=:.:. .:-++==++*+=---::. .:. ......::-=+++*++======++++==-==: .=========--------------====--:..... :+=+==-===----------=======-----=-====: :+==+:==::-==---=======---++=--==----==+: +=-=+--:...:==-==+=:. .==--+=---==+=. .*=-======-:::-==--====--:. .=++: :--. .*=-------=====-====---===+=-. =++. -+========----=+=:-==-----=++++=+. .:::-=-==--==+:...-==-----=+*=. :-:=====+:....:=-------++. :=--:.--......==-------++. .+=-:.......:==--------=+ .====+==----=+=----------== -+=----===++=--:-===-------=- +=------==:. .:===-----=- .+=-----+. .:===---=--::::. .-=+==---== .-==---======= :+==-----=+: -==----==+= :=====+++- :=======- """ ) text_aligner.assert_equal( ascii_drawing(star), """ .:. .:. ::: .:::. .:::. .:::::::::::::::. .:::::::::::::::. .:::::::::::::. ::::::::::: .:::::::. .:::::. ::::::: .:::::::. ::::::::: .:::::::::. .::: :::. ::. .:: . . .:::::::::::::::::::::::::::. ::::::::::::::::::::::::::::: .:::::::::::::::::::::::. .:::::::::::::::::::. ::::::::::::::: ::::::::::::::: .:::::::::::::::. ::::::::.:::::::: .:::::.. ..:::::. ::::. .:::: .. .. """ ) Loading
imgutils/ascii/drawing.py +56 −50 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ __all__ = [ def ascii_drawing(img: ImageTyping, max_width: Optional[int] = ..., max_height: Optional[int] = ..., resample=Image.BILINEAR, levels: str = "@%#*+=-:. "): resample=Image.BILINEAR, levels: str = "@%#*+=-:. ", aspect: float = 1.8): """ Generate ASCII art drawing based on the given image. Loading @@ -30,6 +30,10 @@ def ascii_drawing(img: ImageTyping, max_width: Optional[int] = ..., max_height: :type resample: int :param levels: The characters used to represent different intensity levels in the ASCII art. :type levels: str :param aspect: Proportional correction for ASCII art output, which should approximate the aspect ratio of ASCII characters on your terminal. This value ensures that the aspect ratio of the output ASCII art is as close as possible to the original image. The default value is `1.8`. :type aspect: float :return: The ASCII art representation of the image. :rtype: str Loading @@ -39,57 +43,58 @@ def ascii_drawing(img: ImageTyping, max_width: Optional[int] = ..., max_height: .. image:: ascii_drawing_demo.plot.py.svg :align: center >>> from imgutils.ascii import ascii_drawing [50/1847] >>> from imgutils.ascii import ascii_drawing >>> >>> print(ascii_drawing('jerry.png')) :+- . .===.- ==-=:=: .:: .-*+++-:+. :+++==. .-++***+++: -+==-::= .+*++======:.====-:::-: .=+==--===---====+:::::-= .+*+=-==+=+=-==-=+-::::::= ++===-=++-==----+-:::::::+ :*++=--=++==----=+::::::::= -+=-=-==..=-----=-:::::::-= -+:.=-=: :=-----=-:-:::::=- :+ :=== ==-----==-+:::::+. .= --=: .=-------===::::-+ .+---=- -=-------==:::::+: .:==+===+=.---------=:::::== =++:=-=::-===-----=-::::-+. ..+++.=+- .=++++===-=::::-+. :+=... .:+==--=====:::==. =+: =+===--=+--==: ==... .=+++==+-::. . :::. .-==+**+**++=-..-- .:.--+++*+==--====++++: :=======-----------==--... .===--=-----------------====: =====--=-----=========-----=+. .+-+-=:.-=--=+==-:::+=-==---==- -+-+-:...==-=+: :=-===-==+: ==-=++=:..==--==-: :=+- -=- ==----==--:==---=++-. :+= ==------====+==---=++: ++. .+==-------==:==----=*+=+. .-==+===--=-..-=----=*+- :-:=-==-...==----=* -:====-...:=-----+- .=-:.-:....=-----=+ :=:.......=------+- .++-:....-=------=+ .+==++===++=-------=- +=----==++--==------= .+-----==. .-==----=: .+----== .-==---=. -=---=: :==--===--: .-+=---= -=----==== -===---=: :=----==+ :=----=+: -==---=- -=+++*- :++++= :=++: : =+===+: =: ++----== -*: ..:.. .::=*++++==+. =+-. :=++++++==: .:-*++++****+==+++=. .-++=====--::== .=*++++++++++++===+=. .=++==++=:::::::== :=+++====----===--=---==-=+=-=++-::::::::::*: .-***+=---==-=+++++=----=====--=*=::::::::::::*= :***+=++=---+=++=--=+----=-----+*-:::::::::::::++ .**+*+=-==---=+***=-==---------+*-::::::::::::::*+ =*==*===----=+=:.:+-=---------=*-:::::::::::::::#- ++=+: -=---=+- :+-----------++:::::::::::::::=#. +++. ==--=*- ++-----------=+:::-+::::::::::*+ -+= .+---+- -+=------------====+=:::::::::+#. .++. ==---+. :+=--------------==+=:::::::::=#- .:=*+.=---=*+ .==--------------=+=-:::::::::=#- .=++++==+======*= .=====------------==::::::::::+*- .#+==+:.=---+:..::-+++======-------=+:::::::::-*+: .....:**==+. :++=-. ..:++=======+=====-=+-:::::::-++- :*+=+. .. ..::*+====------====+=:::::-=+=: .=++=. . =*+==++===---=++=---===-: :=+=. -: .:=+++++++===*+-::::.. ... :::::. ..-=====+****+++*****+++=-::..-==-. .::.:--=++++++*#+==-==------======++++++-.. :============-----------------------====--:.. .. -+==+==--==--------------------------------=======+=: -*=-=+-+-==-===-----------===============----------==+- :*=--++.===:..-==-----==++++===-----=*++---=+=------===+- *+---++..::....:=+=--===+=. -==-.:+====-==-=++=- -#=--=++=+==-:....-+=-----===-:.. .===++=-. :=+==+. =#=------======-::::===------==++++=:. .-+==: ... -#=------------=====--=+==-------==++*+: -*=*: +*==--------------====+=-===--------==**=-++=*- -=+++========------=+=:..:===---------=*#+=+= ..:::+=::===---==+:.....:==---------=+#+. .=-..====++=+=.......==----------+#- ==:-===--=+-........+=----------+#- -+=:....::.........+=-----------=*- .+*=:............-+-------------=*: .=+=+++=-:::..::-=+=--------------=*: .=+=----==++++++++*++===-------------=+. ++=----------=+++=-:..:-=+==----------=+. .#=---------=++-. .-=+==--------==. ++---------+- .-=+==------==:. =+=-------+: .-=+=-----=========-. :-=++==-----=+- .-==----------===++ :++=====------=+. -+=--------==+++ -+=--------==++ :++==-------=+. .-=++++++**+-. :=+++++++=-. """ if max_width is ... or max_height is ...: terminal = shutil.get_terminal_size(fallback=(80, 40)) Loading @@ -97,6 +102,7 @@ def ascii_drawing(img: ImageTyping, max_width: Optional[int] = ..., max_height: max_height = terminal.lines - 5 if max_height is ... else max_height img = load_image(img, force_background='white', mode='RGB') img = img.resize((int(img.width * aspect), img.height)) if (max_width is not None and img.width > max_width) or \ (max_height is not None and img.height > max_height): r1 = max_width / img.width if max_width else +math.inf Loading
test/ascii/test_drawing.py +52 −51 Original line number Diff line number Diff line Loading @@ -28,61 +28,62 @@ class TestAsciiDrawing: text_aligner.assert_equal( ascii_drawing(jerry), """ .=-. ==-:. .-++=:=. .-==- =++*++=: .===-:- .-+=======-===:::-. :++======-====::::-: ++===++==---=:::::-: :++=-=--=---=-:::::-: :=.-== :=---=-:::::=. .-.==. =----===::::= .=:==..=-----==:::=: .-=+==+:-=-----=::::= .+=-=-::=====-=-:::=. .+=.-:.-+======::-=. :+: :+===-=---: :-.. :===++--:. .. ...:-++++===++===: -=====-------==--... .=====------===----==- ====::=--====-=+-=--==: .+==::.-===- .=-=--==. :+-===::-=-==-: .== :: .+----=====--===::+: =====--==--=--=+++: ::--=-==..-=--=*- --===..:=---== :-:::...-----+: -=:....=----== .==+=--==-----=: ==--===-:==----- .=---=- :==--=. ==--= -=--=-:: .===-=. .==-==== :=---=- .==--== -==++. .====: -==: : ==--=.-- . .:=+++++-.==. .-=====-. .-*+++***+++==. :=+===-:::=: .:=++============-:===+=-::::::+ .=+++=--==+==+=---===-=+-::::::::+: :*++===--=+++===------=+::::::::::+: ++++==--==-.-==------=+:::::::::::*. +=- -=-=+: ==-------==::-:::::::=+ =+ =--=: :+--------====+:::::::*: -+::=--+. .==---------==+-::::::+- ..:--=+=-===*: -==---------=-:::::::+= .*++=.====:::-++======---==::::::=+: =+== .-:...:++==========+::::-==- -++. . ..=++====---=+------. .-=:.:. .:-++==++*+=---::. .:. ......::-=+++*++======++++==-==: .=========--------------====--:..... :+=+==-===----------=======-----=-====: :+==+:==::-==---=======---++=--==----==+: +=-=+--:...:==-==+=:. .==--+=---==+=. .*=-======-:::-==--====--:. .=++: :--. .*=-------=====-====---===+=-. =++. -+========----=+=:-==-----=++++=+. .:::-=-==--==+:...-==-----=+*=. :-:=====+:....:=-------++. :=--:.--......==-------++. .+=-:.......:==--------=+ .====+==----=+=----------== -+=----===++=--:-===-------=- +=------==:. .:===-----=- .+=-----+. .:===---=--::::. .-=+==---== .-==---======= :+==-----=+: -==----==+= :=====+++- :=======- """ ) text_aligner.assert_equal( ascii_drawing(star), """ .:. .:. ::: .:::. .:::. .:::::::::::::::. .:::::::::::::::. .:::::::::::::. ::::::::::: .:::::::. .:::::. ::::::: .:::::::. ::::::::: .:::::::::. .::: :::. ::. .:: . . .:::::::::::::::::::::::::::. ::::::::::::::::::::::::::::: .:::::::::::::::::::::::. .:::::::::::::::::::. ::::::::::::::: ::::::::::::::: .:::::::::::::::. ::::::::.:::::::: .:::::.. ..:::::. ::::. .:::: .. .. """ )