예제 #1
0
    def test_bottom_hole_B1(self):
        """
        ----------------------
        |      |      |      |
        |------|-------------|
        |      |             |
        |---------------------
        |             |
        ---------------
        """
        page = Page(30, 3)
        self.force_cell_position(0)
        self.prevent_cell_extension()
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        self.force_cell_extension()
        page.add_cell(Photo("img", 10, 5))
        page.add_cell(Photo("img", 10, 5))

        wanted = ("[10 10]  [10 10]  [10 10]\n"
                  "[10 10]  [20 10-- ------]\n"
                  "[20 10-- ------]         ")
        self.assertEqual(repr(page), wanted)

        page.remove_bottom_holes()
        wanted = ("[10 10] [10 10]  [10 10]\n"
                  "[10 10] [20 10-- ------]\n"
                  "        [20 10-- ------]")
        self.assertEqual(repr(page), wanted)
예제 #2
0
class UserCollage(object):
    """Represents a user-defined collage
    A UserCollage contains a list of photos (referenced by filenames) and a
    collage.Page object describing their layout in a final poster.
    """
    def __init__(self, photolist):
        self.photolist = photolist

    def make_page(self, opts):
        # Define the output image height / width ratio
        ratio = 1.0 * opts.out_h / opts.out_w

        # Compute a good number of columns. It depends on the ratio, the number
        # of images and the average ratio of these images. According to my
        # calculations, the number of column should be inversely proportional
        # to the square root of the output image ratio, and proportional to the
        # square root of the average input images ratio.
        avg_ratio = (sum(1.0 * photo.h / photo.w
                         for photo in self.photolist) / len(self.photolist))
        # Virtual number of images: since ~ 1 image over 3 is in a multi-cell
        # (i.e. takes two columns), it takes the space of 4 images.
        # So it's equivalent to 1/3 * 4 + 2/3 = 2 times the number of images.
        virtual_no_imgs = 2 * len(self.photolist)
        no_cols = int(round(math.sqrt(avg_ratio / ratio * virtual_no_imgs)))
        self.page = Page(opts.out_w, ratio, no_cols)

        for photo in self.photolist:
            self.page.add_cell(photo)
        self.page.adjust()
예제 #3
0
 def test_remove_empty_cols(self):
     page = Page(1, 100)
     self.prevent_cell_extension()
     page.add_cell(Photo("img", 10, 10))
     page.add_cell(Photo("img", 10, 10))
     page.add_cell(Photo("img", 10, 10))
     page.add_cell(Photo("img", 10, 10))
     page.add_cell(Photo("img", 10, 10))
     page.remove_empty_cols()
     self.assertEqual(len(page.cols), 5)
예제 #4
0
    def test_bottom_hole_B1(self):
        """
        ----------------------
        |      |      |      |
        |------|-------------|
        |      |             |
        |---------------------
        |             |
        ---------------
        """
        page = Page(30, 0.6, 3)
        self.force_cell_position(0)
        self.prevent_cell_extension()
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        self.force_cell_extension()
        page.add_cell(Photo("img", 10, 5))
        page.add_cell(Photo("img", 10, 5))

        wanted = ("[10 10]  [10 10]  [10 10]\n"
                  "[10 10]  [20 10-- ------]\n"
                  "[20 10-- ------]         ")
        self.assertEqual(repr(page), wanted)

        page.remove_bottom_holes()
        wanted = ("[10 10] [10 10]  [10 10]\n"
                  "[10 10] [20 10-- ------]\n"
                  "        [20 10-- ------]")
        self.assertEqual(repr(page), wanted)
예제 #5
0
 def test_remove_empty_cols(self):
     page = Page(1, 0.6, 100)
     self.prevent_cell_extension()
     page.add_cell(Photo("img", 10, 10))
     page.add_cell(Photo("img", 10, 10))
     page.add_cell(Photo("img", 10, 10))
     page.add_cell(Photo("img", 10, 10))
     page.add_cell(Photo("img", 10, 10))
     page.remove_empty_cols()
     self.assertEqual(len(page.cols), 5)
예제 #6
0
    def make_page(self, opts):
        # Define the output image height / width ratio
        ratio = 1.0 * opts.out_h / opts.out_w

        # Compute a good number of columns. It depends on the ratio, the number
        # of images and the average ratio of these images. According to my
        # calculations, the number of column should be inversely proportional
        # to the square root of the output image ratio, and proportional to the
        # square root of the average input images ratio.
        avg_ratio = (sum(1.0 * photo.h / photo.w
                         for photo in self.photolist) / len(self.photolist))
        # Virtual number of images: since ~ 1 image over 3 is in a multi-cell
        # (i.e. takes two columns), it takes the space of 4 images.
        # So it's equivalent to 1/3 * 4 + 2/3 = 2 times the number of images.
        virtual_no_imgs = 2 * len(self.photolist)
        no_cols = int(round(math.sqrt(avg_ratio / ratio * virtual_no_imgs)))
        self.page = Page(opts.out_w, ratio, no_cols)

        for photo in self.photolist:
            self.page.add_cell(photo)
        self.page.adjust()
예제 #7
0
def run(args):
    tmp_file = []
    tmp_file_photo = []
    if args.user:
        if args.mode == "owned":
            url = owned_url
        elif args.mode == "ordered":
            url = ordered_url
        p = requests.get(url.format(args.user)).content
        url_re = re.compile(r'\<a href="\/item\/(\d+)"')
        fig_ids = re.findall(url_re, p)

        for i in fig_ids:
            u = img_url.format(i)
            q = requests.get(u).content
            print("Downloading " + u)
            if not q or len(q) < 300:
                u = img_url_big.format(i)
                print("Retrying " + u)
                q = requests.get(u).content
            fp = tempfile.NamedTemporaryFile()
            fp.write(q)
            fp.flush()
            tmp_file.append(fp)
    elif args.input:
        for r, d, f in os.walk(args.input):
            for file in f:
                tmp_file.append(open(os.path.join(r, file), 'rb'))

    if args.randomize:
        random.shuffle(tmp_file)

    total_x = total_y = 0
    harmonic_mean_sum = 0
    for i in tmp_file:
        with Image.open(i.name) as img:
            total_x += img.size[0]
            total_y += img.size[1]
            ratio = (1 / (float(total_y) / total_x))
            harmonic_mean_sum += ratio
    harmonic_mean = len(tmp_file) / harmonic_mean_sum
    print(harmonic_mean)

    if not args.collage or args.collage == 1:
        tmp_file_names = map(lambda x: x.name, tmp_file)
        res = make_collage(tmp_file_names, args.output, int(300 * math.sqrt(len(tmp_file))), \
                           harmonic_mean * 300, enlarge=False)
    elif args.collage == 2:
        tmp_file_photo = build_photolist(tmp_file)
        pa = Page(min(4800, total_y / 2), harmonic_mean * 3,
                  int(math.sqrt(len(tmp_file)) * 2))
        for t in tmp_file_photo:
            pa.add_cell(t)
        pa.adjust()
        t = RenderingTask(pa, output_file=args.output, quality=QUALITY_BEST)
        t.start()
    print("Done")
예제 #8
0
    def test_next_free_col(self):
        self.force_cell_position(0)
        self.prevent_cell_extension()

        page = Page(100, 4)
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        wanted = "[25 25] [25 25]  "
        self.assertEqual(repr(page), wanted)

        page = Page(40, 4)
        page.add_cell(Photo("img", 10, 20))
        page.add_cell(Photo("img", 10, 15))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 22))
        wanted = ("[10 20] [10 15] [10 10] [10 10]\n"
                  "        [10 22] [10 10] [10 10]")
        self.assertEqual(repr(page), wanted)

        page = Page(50, 5)
        self.force_cell_extension()
        page.add_cell(Photo("img", 10, 15))
        page.add_cell(Photo("img", 10, 10))
        self.prevent_cell_extension()
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 50))
        wanted = ("[20 30-- ------] [20 20-- ------] [10 10]\n"
                  "                                  [10 50]")
        self.assertEqual(repr(page), wanted)
예제 #9
0
    def test_next_free_col(self):
        self.force_cell_position(0)
        self.prevent_cell_extension()

        page = Page(100, 0.6, 4)
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        wanted = "[25 25] [25 25]  "
        self.assertEqual(repr(page), wanted)

        page = Page(40, 0.6, 4)
        page.add_cell(Photo("img", 10, 20))
        page.add_cell(Photo("img", 10, 15))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 22))
        wanted = ("[10 20] [10 15] [10 10] [10 10]\n"
                  "        [10 22] [10 10] [10 10]")
        self.assertEqual(repr(page), wanted)

        page = Page(50, 0.6, 5)
        self.force_cell_extension()
        page.add_cell(Photo("img", 10, 15))
        page.add_cell(Photo("img", 10, 10))
        self.prevent_cell_extension()
        page.add_cell(Photo("img", 10, 10))
        page.add_cell(Photo("img", 10, 50))
        wanted = ("[20 30-- ------] [20 20-- ------] [10 10]\n"
                  "                                  [10 50]")
        self.assertEqual(repr(page), wanted)
예제 #10
0
def make_collage(output_filename, photos):
    # Define the output image height / width ratio
    ratio = 1.0 * out_h / out_w

    """
    Compute a good number of columns. It depends on the ratio, the number
    of images and the average ratio of these images. According to my
    calculations, the number of column should be inversely proportional
    to the square root of the output image ratio, and proportional to the
    square root of the average input images ratio.
    """
    avg_ratio = sum(
        1.0 * photo_from_list.h / photo_from_list.w for photo_from_list in
        photos) / len(photos)

    """
    Virtual number of images: since ~ 1 image over 3 is in a multi-cell
    (i.e. takes two columns), it takes the space of 4 images.
    So it's equivalent to 1/3 * 4 + 2/3 = 2 times the number of images.
    """
    virtual_no_images = 2 * len(photos)
    no_cols = int(round(math.sqrt(avg_ratio / ratio * virtual_no_images)))

    border_w = 0.01
    border_c = (0, 0, 0)  # black
    # border_c = render.random_color()

    page = Page(1.0, ratio, no_cols)
    random.shuffle(photos)
    for photo_from_list in photos:
        page.add_cell(photo_from_list)
    page.adjust()

    # If the desired ratio changed in the meantime (e.g. from landscape to
    # portrait), it needs to be re-updated
    page.target_ratio = 1.0 * out_h / out_w
    page.adjust_cols_heights()
    page.scale_to_fit(out_w, out_h)
    enlargement = float(out_w) / page.w
    page.scale(enlargement)

    t = render.RenderingTask(
        page, output_file=output_filename,
        border_width=border_w * max(page.w, page.h),
        border_color=border_c)

    t.start()