def list_tiles_for_bounds(image, s2p, paper_width_pt, paper_height_pt, north, west, south, east): """ Return a list of coordinates and scan-to-coord functions for a full set of zoom levels. Internal work is done by list_tiles_for_bounds_zoom(). """ osm = OpenStreetMapProvider() coords = [] for zoom in range(19): # # Coordinates of three print corners # ul = osm.locationCoordinate(Location(north, west)).zoomTo(zoom) ur = osm.locationCoordinate(Location(north, east)).zoomTo(zoom) lr = osm.locationCoordinate(Location(south, east)).zoomTo(zoom) # # Matching points in print and coordinate spaces # ul_pt = Point(1 * ptpin - paper_width_pt, 1.5 * ptpin - paper_height_pt) ul_co = Point(ul.column, ul.row) ur_pt = Point(0, 1.5 * ptpin - paper_height_pt) ur_co = Point(ur.column, ur.row) lr_pt = Point(0, 0) lr_co = Point(lr.column, lr.row) scan_dim = hypot(image.size[0], image.size[1]) zoom_dim = hypot((lr_co.x - ul_co.x) * 256, (lr_co.y - ul_co.y) * 256) if zoom_dim / scan_dim < .05: # too zoomed-out continue if zoom_dim / scan_dim > 3.: # too zoomed-in break # # scan2coord by way of scan2print and print2coord # p2c = triangle2triangle(ul_pt, ul_co, ur_pt, ur_co, lr_pt, lr_co) s2c = s2p.multiply(p2c) coords += list_tiles_for_bounds_zoom(image, s2c, zoom) return coords
def list_tiles_for_bounds(image, s2p, paper_width_pt, paper_height_pt, north, west, south, east): """ Return a list of coordinates and scan-to-coord functions for a full set of zoom levels. Internal work is done by list_tiles_for_bounds_zoom(). """ osm = OpenStreetMapProvider() coords = [] for zoom in range(19): # # Coordinates of three print corners # ul = osm.locationCoordinate(Location(north, west)).zoomTo(zoom) ur = osm.locationCoordinate(Location(north, east)).zoomTo(zoom) lr = osm.locationCoordinate(Location(south, east)).zoomTo(zoom) # # Matching points in print and coordinate spaces # ul_pt = Point(1 * ptpin - paper_width_pt, 1.5 * ptpin - paper_height_pt) ul_co = Point(ul.column, ul.row) ur_pt = Point(0, 1.5 * ptpin - paper_height_pt) ur_co = Point(ur.column, ur.row) lr_pt = Point(0, 0) lr_co = Point(lr.column, lr.row) scan_dim = hypot(image.size[0], image.size[1]) zoom_dim = hypot((lr_co.x - ul_co.x) * 256, (lr_co.y - ul_co.y) * 256) if zoom_dim/scan_dim < .05: # too zoomed-out continue if zoom_dim/scan_dim > 3.: # too zoomed-in break # # scan2coord by way of scan2print and print2coord # p2c = triangle2triangle(ul_pt, ul_co, ur_pt, ur_co, lr_pt, lr_co) s2c = s2p.multiply(p2c) coords += list_tiles_for_bounds_zoom(image, s2c, zoom) return coords
def extract_image(scan2print, print_bbox, scan_img, dest_dim, step=50): """ Extract a portion of a scan image by print coordinates. scan2print - transformation from scan pixels to original print. """ dest_img = Image.new('RGB', dest_dim) # # Compute transformation from print image bbox to destination image. # print2dest = triangle2triangle(Point(print_bbox[0], print_bbox[1]), Point(0, 0), Point(print_bbox[0], print_bbox[3]), Point(0, dest_dim[1]), Point(print_bbox[2], print_bbox[1]), Point(dest_dim[0], 0)) # # Compute transformation from source image to destination image. # scan2dest = scan2print.multiply(print2dest) dest_w, dest_h = dest_dim for y in range(0, dest_h, step): for x in range(0, dest_w, step): # dimensions of current destination cell w = min(step, dest_w - x) h = min(step, dest_h - y) # transformation from scan pixels to destination cell m = scan2dest m = m.multiply(Transform(1, 0, -x, 0, 1, -y)) m = m.inverse() a = m.affine(0, 0, w, h) p = scan_img.transform((w, h), AFFINE, a, BICUBIC) dest_img.paste(p, (x, y)) return dest_img