Navigation

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Users
    • Groups
    • Solved
    • Unsolved
    • Search
    1. Home
    2. eduairet
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    Eduardo Aire Torres

    @eduairet

    Letters & images maker

    1
    Reputation
    40
    Posts
    112
    Profile views
    0
    Followers
    6
    Following
    Joined Last Online
    Email hola@eduairet.com Website eduairet.com Location Mexico City Age 28

    eduairet Follow

    Best posts made by eduairet

    • Unknown Pleasures Tutorial

      Hey there I was playing trying to recreate the Unknown Pleasures cover art, and this is the result if you've ever done it before I would love to see how did you solve it.

      Cheers!!

      # Tribute for Joy Division's Unknown Pleasures album cover
      
      side = 1080
      
      def lsPts(num):
          points = []
          m = side*0.3
          for i in range(0, side, 12):
              if i <= side*0.2:
                  x = i
                  y = sin((i*(randint(1, 3))))
                  points.append((x, y))
              if i > side*0.2 and i <= side*0.4:
                  x = i
                  y = i*sin(radians(i*(randint(-100, 100))))/(10**1)
                  if y < 0:
                      points.append((x, y * -1))
                  else:
                      points.append((x, y))
              if i > side*0.4 and i <= side*0.6:
                  x = i
                  y = m*sin(radians(m*(randint(-100, 100))))/(10**1)
                  if y < 0:
                      points.append((x, y * -1))
                  else:
                      points.append((x, y))
                  m -= 1
              if i > side*0.6 and i <= side*0.8:
                  x = i
                  y = sin((i*(randint(1, 3))))
                  points.append((x, y))
          return points
      
      def lineGrid(steps):
          for j in range(steps):
              newPage(side, side)
              fill(0)
              rect(0, 0, side, side)
              m = 0
              for i in range(int(side*0.8/13.5)):
                  points = lsPts(1)
                  fill(None)
                  stroke(1)
                  strokeWidth(1)
                  path = BezierPath()
                  with savedState():
                      translate(side*0.1, side*0.1 + m)
                      path.moveTo((0, 0))
                      path.curveTo(*points)
                      drawPath(path)
                  m += 13.5
      
      for i in range(12):
          lineGrid(i)
      
      saveImage('~/Desktop/unknown_pleasures.gif')
      
      posted in Tutorials
      eduairet
      eduairet

    Latest posts made by eduairet

    • RE: Gradient rings from Python for Designers tutorial

      @frederik thank you very much! 😊 I'll implement this way

      posted in Tutorials
      eduairet
      eduairet
    • Gradient rings from Python for Designers tutorial

      Hello everyone!!!

      I'm attempting to solve the ex­er­cise 14.4 of @roberto-arista 's pythonfordesigners.com/chapters/workbook/ I'm having a problem with my approach, I decided to use circles instead of lines and I couldn't find a way to make a smooth gradient without having a weird hole 🕳 in the middle of the right top and right bottom blending, here's a photo of it:

      Screen Shot 2021-01-11 at 13.55.29.png

      # 14.4
      def donuts(circSize=10, cnvSize=200):
          
          def intrp(factor, val1, val2):
              return val1 + (val2 - val1) * factor
              
          def intrRgb(factor, col1, col2):
              r = intrp(factor, col1[0], col2[0])
              g = intrp(factor, col1[1], col2[1])
              b = intrp(factor, col1[2], col2[2])
              return r, g, b
              
          def circCoords(radius, circSize=10):
              cirCoords = []
              an = 0
              anMulti = 0
              for i in range(cnvSize+1):
                  for j in range(cnvSize):
                      cirCoords.append([
                          radius * sin(pi * 2 * an / 360) - halfCirc,
                          radius * cos(pi * 2 * an / 360) - halfCirc
                      ])
                      an += 360/(cnvSize*cnvSize)
              return sorted(cirCoords)
              
          def mapColors(c1, c2, c3, c4):
              colors = []
              for x in range(cnvSize):
                  xFactor = x/cnvSize
                  for y in range(cnvSize):
                      yFactor = y / cnvSize
                      lftClr = intrRgb(yFactor, c4, c1)
                      rgtClr = intrRgb(yFactor, c3, c2)
                      colors.append(intrRgb(xFactor, lftClr, rgtClr))       
              return colors
          
          halfCirc = circSize/2
          colors = {'lftTop': (1, 0, 0.8), 'rgtTop': (1, 1, 0.3), 'rgtBtm': (1, .8, 0), 'lftBtm': (0, 0.5, 1)} 
          
          colors = mapColors(colors['lftTop'], colors['rgtTop'], colors['rgtBtm'], colors['lftBtm'])
          circles = [circCoords(cnvSize*0.4, circSize), circCoords(cnvSize*0.25, circSize), circCoords(cnvSize*0.1, circSize)]
          
          newPage(cnvSize, cnvSize)
          inc = 0
          for x in range(cnvSize):
              for y in range(cnvSize):
                  fill(*colors[inc])
                  if x == 0 and y == 0 or x == 0 and y == cnvSize-1 or x == cnvSize-1 and y == 0 or x == cnvSize-1 and y == cnvSize-1:
                      oval(x - halfCirc, y - halfCirc, circSize, circSize)
                  if y == int(circles[0][inc][1]) + cnvSize/2 - 1 or y == int(circles[0][inc][1]) + cnvSize - 100:
                      for circ in circles:
                          with savedState():
                              translate(cnvSize/2, cnvSize/2)
                              oval(circ[inc][0], circ[inc][1], circSize, circSize)
                  inc += 1
      
      # Call the function
      donuts()
      

      Hope you can help me, feedback on my approach would be great too, thank you!!!!!!!

      posted in Tutorials
      eduairet
      eduairet
    • RE: how to code a gif that gradually transform one picture into another

      Hi, hope this helps:

      # Get your gif routes
      gifsFolder = '.' # Your gifs directory
      gifs = ['gif1.gif', 'gif2.gif'] # These are the files I'll use
      gifPaths = [f'{gifsFolder}/{gif}' for gif in gifs] # Create the paths for your with string formattingx
      
      # Create a function to interpolate between gifs
      
      def scaleFactor(path, pageNumber, canvasSize): # Get a scale factor to match the canvas size you want
          gifw, gifh = imageSize(path, pageNumber=pageNumber)
          factorMeasure = gifw
          if gifw > gifh:
              factorMeasure = gifh
          return  canvasSize / factorMeasure
      
      def gifTransition(path1, path2):
          # Canvas and images dimensions
          w, h = 200, 200 # Canvas size
          
          # Define your frames
          introFrames = numberOfPages(path1)
          endingFrames = numberOfPages(path2)
          crossfadeFrames = 12 # Change this value for a longer transition
          totalFrames = int(
              (introFrames - crossfadeFrames/2)+(endingFrames - crossfadeFrames/2)
              ) # Get the total frames by merging the crossfade in the middle 
          
          # Make a loop for the animation
          gif1Frames, gif2Frames = 0, 0
          gif1alpha, gif2alpha = 1, 0
          for frame in range(1, totalFrames+1):
              newPage(w, h)
              fill(1)
              rect(0, 0, w, h)
              with savedState():
                  scale(scaleFactor(path1, gif1Frames, w))
                  image(path1, (0, 0), pageNumber=gif1Frames, alpha=gif1alpha)
              if gif1Frames < introFrames:
                  gif1Frames += 1
              if frame > introFrames - crossfadeFrames/2: # Run the second gif
                  with savedState():
                      scale(scaleFactor(path2, gif2Frames, w))
                      image(path2, (0, 0), pageNumber=gif2Frames, alpha=gif2alpha)
                  gif2Frames += 1
                  if gif1alpha >= 0 or gif2alpha <= 1: # Crossfade transparency
                      gif1alpha -= 1 / crossfadeFrames
                      gif2alpha += 1 / crossfadeFrames
                  
      gifTransition(gifPaths[0], gifPaths[1]) # Call the function
      saveImage('~/Desktop/gifCrossfade.gif') # Save your gif
      
      posted in General Discussion
      eduairet
      eduairet
    • RE: Tutorial Request: Delay Animation

      @vitorcarvalho wow, this is lovely!!!

      posted in Tutorials
      eduairet
      eduairet
    • RE: Tutorial Request: Delay Animation

      I found this very interesting so I tried to do it without a lot of success, I ended with something like this:

      w, h = 1000, 1000
      divs = 10
      colSize, rowSize = w//divs, h//divs
      fps = 12
      seconds = 1
      duration = 1 / fps
      totalFrames = seconds * fps
      
      def circles(step):
          for x in range(0, w, colSize):
              for y in range(0, h, rowSize):
                  d = rowSize * sin(y/(divs/2)+step)
                  if d > 0:
                      fill(1)
                  else:
                      fill(1, 0, 0)
                  oval(x + colSize/2 - d/2, y + rowSize/2 - d/2 , d, d)
       
      for frame in range(totalFrames):
          newPage(w, h)
          frameDuration(duration)
          fill(0)
          rect(0, 0, w, h)
          circles(frame)
              
      saveImage("~/Desktop/circleTest.gif")
      

      I'm not understanding how the time works in the reference to achieve the smooth variation

      posted in Tutorials
      eduairet
      eduairet
    • Vertical Align

      I'm looking for a property to work with textBox() to align the text to the vertical center. What I'm imagining is something like this:

      textBox(
          'DrawBot is great',
          (
              width()*0.2,
              height()*0.2,
              width()*0.6,
              height()*0.6
          ),
          align = 'center',
          verticalAlign = 'center'
      )
      

      This way you can come up with a random playing with that verticalAlign or something like that 😊

      posted in Feature Requests
      eduairet
      eduairet
    • RE: Loop image generation breaks at index 16

      @frederik OMG it works now!!! thank you very much!!!! 😊 Happy holidays!!!

      posted in General Discussion
      eduairet
      eduairet
    • RE: Loop image generation breaks at index 16

      Here a handy script to generate files to test, if you use it this way you should change the following line:

      if len(row['\ufeffNAME']) > 0:
                data.append(row['\ufeffNAME'])
      

      to

      if len(row['NAME']) > 0:
                data.append(row['NAME'])
      
      import os
      import csv
      
      def fullNameGenerator():
          name = ''
          lastName = ''
          for letter in range(randint(4,10)):
              name += choice(letters)
          for letter in range(randint(4,10)):
              lastName += choice(letters)      
          fullName = name.title() + ' ' + lastName.title()
          return fullName
      
      letters = 'abcdefghijklmnopqrstuvwxyz'
      myMessage ='I wish you the best holidays ever! With All my love for you:'
      
      myPath = './'
      myDir = 'dataFiles'
      myDirPath = myPath + myDir
      if myDir not in os.listdir(myPath):
          os.mkdir(myPath + myDir)
      
      with open(myDirPath + '/xmasMessage.txt', 'w') as xmasMsg: 
          xmasMsg.write(myMessage)
          
      with open(myDirPath + '/xmasList.csv', 'w', newline='') as xmasList:
          csv_writter = csv.writer(xmasList)
          
          csv_writter.writerow(['NAME'])
          
          names = []
          for i in range(40):
              names.append([fullNameGenerator()])
      
          for row in names:
              csv_writter.writerow(row)
      

      And the snowflake pdf
      https://drive.google.com/file/d/1EZxopDsOjd-K7ur-QQm-Xc_0zj7dGPkv/view?usp=sharing

      Thanks again!!

      posted in General Discussion
      eduairet
      eduairet
    • Loop image generation breaks at index 16

      Hi, I'm making custom Christmas gif postcards, everything's working until the loop reaches the 16th value of my list, I tried making them individually and it works, but when I try a for loop it gets stuck like in an infinite loop but I don't know why. Does anyone know what's happening?

      import csv
      import unicodedata
      import os
      
      def strip_accents(text):
          try:
              text = unicode(text, 'utf-8')
          except NameError: # unicode is a default on python 3 
              pass
          text = unicodedata.normalize('NFD', text)\
                 .encode('ascii', 'ignore')\
                 .decode("utf-8")
          return str(text)
      
      # Typeface
      canelaUnordered = []
      for font in installedFonts():
          if 'Canela' in font:
              canelaUnordered.append(font)
      canelaIndexes = [2, 3, 0, 1, 8, 9, 6, 7, 4, 5, 14, 15, 12, 13, 10, 11]
      canela = []
      for i in range(len(canelaUnordered)):
          canela.append(canelaUnordered[canelaIndexes[i]])    
      
      # Data for custom images
      data = []
      with open('./xmasList.csv', newline='', encoding='UTF-8') as data_csv:
        data_reader = csv.DictReader(data_csv,  delimiter=',', quotechar='|')
        for row in data_reader:
            if len(row['\ufeffNAME']) > 0:
                data.append(row['\ufeffNAME'])
                
      # Main copywrite
      cw = open('./xmasMessage.txt', 'r', encoding='UTF-8')
      cw = cw.read()  
                
      # Design class
      class Postcard():
          
          def __init__(self, x=1600, y=1600, m=160):
              self.x = x
              self.y = y
              self.m = m 
              self.tree = BezierPath()
              self.tree.moveTo((self.m, self.y*0.18))
              self.tree.lineTo((self.x/2, self.y *0.90))
              self.tree.lineTo((self.x - (self.m), self.y*0.18))
              self.tree.closePath()
      
          def c(self, val):
              if type(isinstance(val, (int, float))):
                  if val <= 255:
                      return val / 255
                  else:
                      raise Exception("Sorry, just numbers below 255")
          
          def hexToRGB(self, val):
              val = val.lstrip('#')
              lv = len(val)
              color = [int(val[i:i + lv // 3], 16) for i in range(0, lv, lv // 3)]
              r, g, b = color[0], color[1], color[2]
              return self.c(r), self.c(g), self.c(b)
          
          def copy(self, cw = cw):
              self.cw = cw
              words = self.cw.split()
              txtFillone = self.hexToRGB('#FFFFFF')
              txt = FormattedString(
                  '•\n',
                  font = canela[1],
                  fontSize=160,
                  lineHeight=200,
                  fill = (txtFillone[0], txtFillone[1], txtFillone[2]),
                  align = 'center'
                  )
              
              txt.append('2020\n'.upper(), font=canela[1], fontSize=158, lineHeight=159)
              txt.append('Merry '.upper(), font = canela[4], fontSize=94, lineHeight=100)
              txt.append('Xmas'.upper() + '\n•\n', font = canela[2])
              
              boldWords = ['holidays']
              breakWords = ['ever!']
              
              for word in words:
                  txt.append('', fontSize=48, lineHeight=52, paragraphBottomSpacing=52)
                  if word in boldWords:
                      txt.append(word + ' ', font = canela[13])
                  elif word in breakWords:
                      txt.append(word + '\n', font = canela[13])
                  else:
                      txt.append(word + ' ', font = canela[11])
                  
              logo = FormattedString(
                  'Sincerely eat\n',
                   align='center', font = canela[10], fontSize=80, lineHeight=180, fill=(1)
                  )
                  
              textBox(txt, self.tree)
              text(logo, (self.x/2, self.m))
              
          def receiver(self, tx, limit = 100):
              rFnt = canela[2]
              textSize = FormattedString(tx, font = rFnt, fontSize=1, lineHeight=1, align='center')
              rSz = 1180 / textSize.size()[0]
              if rSz > limit:
                  rSz = limit
              receiver = FormattedString(tx,font=rFnt, fontSize=rSz, lineHeight=rSz, align='center', fill=(1))
              text(receiver, (self.x/2, self.y*0.20))
              stroke(2)
              strokeWidth(6)
              line((self.x*0.17, self.y*0.28), (self.x*0.83, self.y*0.28))
              
          def snow(self, copos=30, path='./snowFlake.pdf'):
              w, h = imageSize(path)
              copo = ImageObject(path)
              for i in range(copos):
                  scaleFactor = randint(1, 5) * 0.1
                  with savedState():
                      translate(randint(0, self.x), randint(self.y*0.12, self.y))
                      scale(scaleFactor)
                      image(copo, (-w/2, -h/2))
          
          def canvas(self, bgColor='#FF5900'):
              newPage(self.x, self.y)
          
              if type(bgColor) == list:
                  self.bgColor = self.c(bgColor[0]), self.c(bgColor[1]), self.c(bgColor[2])
              elif type(bgColor) == str:
                  if len(bgColor) == 7 or len(bgColor) == 4 or len(bgColor) == 6 or len(bgColor) == 3: 
                      self.bgColor = self.hexToRGB(bgColor)
                  else:
                      raise Exception("Sorry, incorrect HexValue")
              else:
                  raise Exception("Sorry, use one of the following formats: [r, g, b] or Hex value")
      
              fill(self.bgColor[0], self.bgColor[1], self.bgColor[2])
              rect(0, 0, self.x, self.y)
          
          def drawTree(self, deg):
              fill(0.1, 0.4, 0.3)
              stroke(0.1, 0.4, 0.3)
              strokeWidth(100)
              with savedState():
                  rotate(deg, center=(self.x/2, self.y/2))
                  drawPath(self.tree)
              
          def save(self, tx, user='eat', message='merryXmas2020'):
              fileName = strip_accents(tx).lower().strip().replace(' ', '_')
              saveDir = '2020_xmasCards'
              saveLoc = '/Users/{}/Desktop/'.format(user)
              if saveDir not in os.listdir(path=saveLoc):
                  os.mkdir(saveLoc + saveDir)
              saveImage(saveLoc + saveDir + '/' + message + '_{}.gif'.format(fileName), imageResolution = 72)
              print(message + '_{}.gif'.format(fileName) + ' Done')
              newDrawing()
      
      def postcardGenerator(data, save=True, frames = 2):
          deg = 2
          rot = -2
          for i in range(frames): 
              card = Postcard()    
              card.canvas()
              card.drawTree(deg)
              card.snow()
              card.copy()
              card.receiver(data)
              if i == int(frames/2):
                  rot *= -1
              deg += rot
          if save:
              card.save(data)
      
      # Ceate postcards
      for field in data:
          postcardGenerator(field)
      
      # testNum = 0
      # postcardGenerator(data[testNum], False)
      

      If you make the whole list with the testNum it works which makes me think that the problem is not in the external files I'm using.

      Thank you for your help!!

      posted in General Discussion
      eduairet
      eduairet
    • RE: QRCodeGenerator(size, message)

      @gferreira WOW!!!! you saved my ass again, you're amazing, thanks a lot!!!

      posted in General Discussion
      eduairet
      eduairet