code: def largest_rotated_rect(w, h, angle):
          
          angle = angle / 180.0 * math.pi
          if w <= 0 or h <= 0:
              return 0, 0
  
          width_is_longer = w >= h
          side_long, side_short = (w, h) if width_is_longer else (h, w)
  
          # since the solutions for angle, -angle and 180-angle are all the same,
          # if suffices to look at the first quadrant and the absolute values of sin,cos:
          sin_a, cos_a = abs(math.sin(angle)), abs(math.cos(angle))
          if side_short <= 2. * sin_a * cos_a * side_long:
              # half constrained case: two crop corners touch the longer side,
              #   the other two corners are on the mid-line parallel to the longer line
              x = 0.5 * side_short
              wr, hr = (x / sin_a, x / cos_a) if width_is_longer else (x / cos_a, x / sin_a)
          else:
              # fully constrained case: crop touches all 4 sides
              cos_2a = cos_a * cos_a - sin_a * sin_a
              wr, hr = (w * cos_a - h * sin_a) / cos_2a, (h * cos_a - w * sin_a) / cos_2a
          return int(np.round(wr)), int(np.round(hr))
docs: Get largest rectangle after rotation.
          http://stackoverflow.com/questions/16702966/rotate-image-and-crop-out-black-borders