Home > Enterprise >  Where should I define 'fileName' in my program?
Where should I define 'fileName' in my program?

Time:01-10

When running the program below I recieve the error:

  File "/home/kali/ascii.py", line 16, in <module>
    image = Image.open(fileName).convert('L')
NameError: name 'fileName' is not defined

Excuse the amount of comments. I am new to programming and am trying to take notes as I go along.

# For this program to work we need to import Pillow (fork of PIL) and Numpy
import sys, random, argparse
import numpy as np
from PIL import Image
import math

# gscale1 (Grayscale1) is a 70 level grayscale ramp. gscale2 is a simpler 10 level ramp
gscale1 = '$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_ ~i!lI;:,\"^`".' 
gscale2 = "@%#* =-:. "

def convertImageToAscii(fileName, cols, scale, moreLevels):
   global gscale1, gscale2


# Opens the image and converts to grayscale using the Pillow library
image = Image.open(fileName).convert('L')

# Stores image height and width
W, H = image.size[0], image.size[1] # Notice 'W' on this line. It is being used in the next line. Same for 'H'

# Computes width of each image 'tile'
w = W/cols

# Computes tile height based on aspect ratio and scale
h = w/scale

# Calculating the number of rows needed
rows = int(H/h) # In other words; Height of the image divided by tile height

# Calculating average brightness
def getAverageBrightness(image):
   im = np.array(image) # Converts image in to Numpy array. At this point the 'im' becomes a 2d array of brightness for each pixel
   w,h = im.shape # Calculates 'shape' of the image aka the dimensions
   return np.average(im.reshape(w*h)) #  Computes average brightness. Uses 'reshape' to convert 2d array of w and h into 1d array whose length is a product of the width times height (w*h). np.average then computes average. 

# The ASCII image is first stored as a list of strings
asciiimg = []


# Below iterates through the calculated number of rows image tiles
for j in range(rows):
   y1 = int(j*h)
# Below line calculates the start and end Y coordinates
   y2 = int((j 1)*h)

# Dont fully understand these next couple of lines yet.
if j == rows-1:
   y2 = H

# Below inserts an empty string in the current image row that will be filled in later.
   aimg.append("")
   for i in range(cols):
   # Crop image to tile
      x1 = int(i*w)
      x2 = int((i 1)*w)
   # Dont understand
   if i == cols -1:
      x2 = W
   # Dont understand
   img = image.crop((x1, y1, x2, y2))
   # Below line calculates average brightness with function defined on line 26. I think this is built in to python.
   avg = int(getAverageBrightness(img))
   # Calculates which ASCII character is needed for each tile by scaling down the brightness value so it fits out previously defined grayscale ramps at the start of this file.
   if moreLevels:
      gsval = gscale1[int((avg*69)/255)]
   else:
      gsval = gscale2[int((avg*9)/255)]
   # Append ASCII character to string
      aimg[j]  = gsval


def main():
   descStr = "This program converts an image to ASCII art and writes it in to a new text file"
   parser = argparse.ArgumentParser(description=descStr)

   parser.add_argument('--file', dest='imgFile', required=True)
   parser.add_argument('--scale', dest='scale', required=False)
   parser.add_argument('--out', dest='outFile', required=False)
   parser.add_argument('--morelevels', dest='moreLevels', action='store_true')
   parser.add_argument('--cols', dest='cols', required=False) 

  
   args = parser.parse_args()
   imgFile = args.imgFile

   outFile = 'out.txt'
   if args.outFile:
      outFile = args.outFile

   scale = 0.43
   if args.scale:
      scale = float(args.scale)


   cols = 80
   if arg.cols:
      cols = int(arg.cols)

   print('generating ASCII art...')
   aimg = convertImageToAscii(imgFile, cols, scale, args.moreLevels)

   f = open(outFile, 'w')

   for row in aimg:
      f.write(row   '\n')

   f.close()
   print("ASCII art written to %s" % outFile)


if __name__ == '__main__':
   main()

This is a program that takes an image file as input and then writes an ASCII art version of that image in to a new text file.

I actually understand the error message to an extent but can't see and difference between the working and my code that would make a difference.

A working version of this program can be found here: https://raw.githubusercontent.com/electronut/pp/master/ascii/ascii.py

Apparently it is based on a project that can be found in the "Python Playground" book.

Thanks in advance for any help :-)

CodePudding user response:

Indentation matters in python, and since fileName is only a parameter in the function, it is local by default, so it is only defined in that function's scope. So indent your code like this:

def convertImageToAscii(fileName, cols, scale, moreLevels):
   global gscale1, gscale2
    # Opens the image and converts to grayscale using the Pillow library
    image = Image.open(fileName).convert('L')

    # Stores image height and width
    W, H = image.size[0], image.size[1] # Notice 'W' on this line. It is being used in the next line. Same for 'H'

    # Computes width of each image 'tile'
    w = W/cols

    # Computes tile height based on aspect ratio and scale
    h = w/scale

    # Calculating the number of rows needed
    rows = int(H/h) # In other words; Height of the image divided by tile height

Full code:

# For this program to work we need to import Pillow (fork of PIL) and Numpy
import sys, random, argparse
import numpy as np
from PIL import Image
import math

# gscale1 (Grayscale1) is a 70 level grayscale ramp. gscale2 is a simpler 10 level ramp
gscale1 = '$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_ ~i!lI;:,\"^`".' 
gscale2 = "@%#* =-:. "

def convertImageToAscii(fileName, cols, scale, moreLevels):
   global gscale1, gscale2
    # Opens the image and converts to grayscale using the Pillow library
    image = Image.open(fileName).convert('L')

    # Stores image height and width
    W, H = image.size[0], image.size[1] # Notice 'W' on this line. It is being used in the next line. Same for 'H'

    # Computes width of each image 'tile'
    w = W/cols

    # Computes tile height based on aspect ratio and scale
    h = w/scale

    # Calculating the number of rows needed
    rows = int(H/h) # In other words; Height of the image divided by tile height

# Calculating average brightness
def getAverageBrightness(image):
   im = np.array(image) # Converts image in to Numpy array. At this point the 'im' becomes a 2d array of brightness for each pixel
   w,h = im.shape # Calculates 'shape' of the image aka the dimensions
   return np.average(im.reshape(w*h)) #  Computes average brightness. Uses 'reshape' to convert 2d array of w and h into 1d array whose length is a product of the width times height (w*h). np.average then computes average. 

# The ASCII image is first stored as a list of strings
asciiimg = []


# Below iterates through the calculated number of rows image tiles
for j in range(rows):
   y1 = int(j*h)
# Below line calculates the start and end Y coordinates
   y2 = int((j 1)*h)

# Dont fully understand these next couple of lines yet.
if j == rows-1:
   y2 = H

# Below inserts an empty string in the current image row that will be filled in later.
   aimg.append("")
   for i in range(cols):
   # Crop image to tile
      x1 = int(i*w)
      x2 = int((i 1)*w)
   # Dont understand
   if i == cols -1:
      x2 = W
   # Dont understand
   img = image.crop((x1, y1, x2, y2))
   # Below line calculates average brightness with function defined on line 26. I think this is built in to python.
   avg = int(getAverageBrightness(img))
   # Calculates which ASCII character is needed for each tile by scaling down the brightness value so it fits out previously defined grayscale ramps at the start of this file.
   if moreLevels:
      gsval = gscale1[int((avg*69)/255)]
   else:
      gsval = gscale2[int((avg*9)/255)]
   # Append ASCII character to string
      aimg[j]  = gsval


def main():
   descStr = "This program converts an image to ASCII art and writes it in to a new text file"
   parser = argparse.ArgumentParser(description=descStr)

   parser.add_argument('--file', dest='imgFile', required=True)
   parser.add_argument('--scale', dest='scale', required=False)
   parser.add_argument('--out', dest='outFile', required=False)
   parser.add_argument('--morelevels', dest='moreLevels', action='store_true')
   parser.add_argument('--cols', dest='cols', required=False) 

  
   args = parser.parse_args()
   imgFile = args.imgFile

   outFile = 'out.txt'
   if args.outFile:
      outFile = args.outFile

   scale = 0.43
   if args.scale:
      scale = float(args.scale)


   cols = 80
   if arg.cols:
      cols = int(arg.cols)

   print('generating ASCII art...')
   aimg = convertImageToAscii(imgFile, cols, scale, args.moreLevels)

   f = open(outFile, 'w')

   for row in aimg:
      f.write(row   '\n')

   f.close()
   print("ASCII art written to %s" % outFile)


if __name__ == '__main__':
   main()
  •  Tags:  
  • Related