def capture(self, path): # NOTE: To obtain the "real" Canon ISO value, we multiply the # "market" value from the config by 0.65. # See core/shooting.c#~l150 in the CHDK source for more details sensitivity = int(self.config["sensitivity"].get()) shutter_speed = float( Fraction(self.config["shutter_speed"].get(unicode))) shoot_raw = self.config['shoot_raw'].get(bool) if self._can_remote: cmd = ("remoteshoot -tv={0} -sv={1} {2} \"{3}\"".format( shutter_speed, sensitivity * 0.65, "-dng" if shoot_raw else "", path)) else: cmd = ("shoot -tv={0} -sv={1} -dng={2} -rm -dl \"{3}\"".format( shutter_speed, sensitivity * 0.65, int(shoot_raw), path)) try: self._run(cmd) except CHDKPTPException as e: if 'not in rec mode' in e.message: self.prepare_capture(None) self.capture(path) else: self.logger.warn("Capture command failed.") raise e extension = 'dng' if shoot_raw else 'jpg' local_path = "{0}.{1}".format(path, extension) # Set EXIF orientation self.logger.debug("Setting EXIF orientation on captured image") img = JPEGImage(local_path) if self.target_page == 'odd': img.exif_orientation = 6 # -90° else: img.exif_orientation = 8 # 90° img.save(local_path)
def scale_image_to_fit_size(path: str, size: Size): desired_width, desired_height = size img = JPEGImage(path) if img.width < desired_width and img.height < desired_height: return bytes(img.data) downscaled_image = img.downscale(*proportionally_scale_dimensions(img, size), quality=90) return bytes(downscaled_image.data)
def hashcalc(path, pool, method="MD5", havejpeginfo=False): rots = [0, 90, 180, 270] # Check file integrity using jpeginfo if available if havejpeginfo: try: devnull = open(os.devnull, 'w') check_call(["jpeginfo", "-c", path], stdout=devnull, stderr=devnull) except: sys.stderr.write(" Corrupt JPEG, skipping\n") return ["ERR"] try: img = JPEGImage(path) lista = [] for rot in rots: lista.append((img, rot, method)) except IOError: sys.stderr.write( " *** Error opening file %s, file will be ignored\n" % path) return ["ERR"] try: results = pool.map(phash, lista) except: sys.stderr.write( " *** Error reading image data, it will be ignored\n") return ["ERR"] return results
def do_crop(fname, left, top, width, height): if HAS_JPEGTRAN: img = JPEGImage(fname) else: img = Image(filename=fname) width = (img.width - left) if width is None else width height = (img.height - top) if height is None else height if width > (img.width - left): width = img.width - left if height > (img.height - top): width = img.height - top if (left, top, width, height) == (0, 0, img.width, img.height): self._logger.warn("No-op crop parameters, skipping!") return self._logger.debug("Cropping \"{0}\" to x:{1} y:{2} w:{3} h:{4}" .format(fname, left, top, width, height)) try: cropped = img.crop(left, top, width=width, height=height) if HAS_JPEGTRAN: cropped.save(fname) else: img.save(filename=fname) img.close() except Exception as e: self._logger.error("Cropping failed") self._logger.exception(e)
def crop_an_imageset(imageset_n): print(CROPDIM) print(os.getcwd()) os.makedirs(imageset_n, exist_ok=True) images_n = os.listdir("../dataset/" + imageset_n) isovals = get_iso_vals(images_n) for isoval in isovals: os.makedirs(imageset_n + "/" + isoval, exist_ok=True) images_in = [None] * len(images_n) for i in range(0, len(images_n)): images_in[i] = JPEGImage("../dataset/" + imageset_n + "/" + images_n[i]) print(imageset_n) image_width = math.floor(images_in[0].width / CROPDIM) * CROPDIM image_height = math.floor(images_in[0].height / CROPDIM) * CROPDIM curx = cury = cnt = 0 while cury < image_height: for i in range(0, len(images_n)): if not os.path.exists(imageset_n + "/" + isovals[i] + "/" + rename_img(images_n[i], cnt)): images_in[i].crop(curx, cury, CROPDIM, CROPDIM).save(imageset_n + "/" + isovals[i] + "/" + rename_img(images_n[i], cnt)) cnt += 1 curx += CROPDIM if curx == image_width: curx = 0 cury += CROPDIM return 1
def scale_image(img_name, width=None, height=None): if width is None and height is None: raise ValueError("Please specify either width or height") img = JPEGImage(img_name) aspect = img.width/img.height width = width if width else int(aspect*height) height = height if height else int(width/aspect) return img.downscale(width, height).as_blob()
def _get_img_response(self, id, thumb=True): path = "{0}/raw/{1}.jpg".format(self.scanner_service.working_dir, id) headers = { 'Content-Type': 'image/jpg' } image = JPEGImage(path) if thumb: image = image.downscale(500, 375) body = image.as_blob() return HTTPResponse(body, **headers)
def rotate_photos(self, p_left_photo, p_right_photo): pictures_found = False tries = 0 while not pictures_found: try: save_path = self.working_dir + '/raw/' left = JPEGImage(save_path + p_left_photo + ".jpg") right = JPEGImage(save_path + p_right_photo + ".jpg") left.rotate(270).save(save_path + p_left_photo + ".jpg") right.rotate(90).save(save_path + p_right_photo + ".jpg") pictures_found = True except: print('Pictures not found yet') time.sleep(0.5) if tries > 20: raise Exception tries += 1
def autorotate_image(path): img = JPEGImage(path) if img.exif_orientation is None: logger.warn( "Image {0} did not have any EXIF rotation, did not rotate.".format( path)) return elif img.exif_orientation == 1: logger.info("Image {0} is already rotated.".format(path)) return rotated = img.exif_autotransform() rotated.save(path)
def capture(self, path): imgdata = self._camera.capture() # Set EXIF orientation self.logger.debug("Setting EXIF orientation on captured image") img = JPEGImage(blob=imgdata) upside_down = self.config["upside_down"].get(bool) if self.target_page == 'odd': img.exif_orientation = 8 if upside_down else 6 # -90° else: img.exif_orientation = 6 if upside_down else 8 # 90° img.save(unicode(path))
def autorotate_image(in_path, out_path): img = JPEGImage(in_path) if img.exif_orientation is None: logger.warn( "Image {0} did not have any EXIF rotation, did not rotate.". format(in_path)) return elif img.exif_orientation == 1: logger.info("Image {0} is already rotated.".format(in_path)) shutil.copyfile(in_path, out_path) else: rotated = img.exif_autotransform() rotated.save(out_path)
def hashcalc(path,pool,method="MD5"): rots=[0,90,180,270] try: img=JPEGImage(path) lista=[] for rot in rots: lista.append((img,rot,method)) except IOError: sys.stderr.write(" *** Error opening file %s, file will be ignored\n" % path) return ["ERR"] results=pool.map(phash,lista) return results
def rotate(self, request, pk=None): check_request_data_for(request, ['rotation']) rotation = int(request.data['rotation']) acceptable_rotations = [90, 180, 270] if rotation not in acceptable_rotations: raise ParseError('Can only rotate by {} degrees.'.format(', '.join(map(str, acceptable_rotations)))) photo = Photo.objects.get(id=pk) img = JPEGImage(photo.path) img = img.rotate(rotation) img.save(photo.path) photo.landscape_orientation = (img.width > img.height) photo.save() return Response(PhotoSerializer(photo, context={'request': None}).data)
def get_thumbnail(img_path): """ Return thumbnail for image. :param img_path: Path to image :type img_path: pathlib.Path :return: The thumbnail :rtype: bytestring """ thumb = JPEGImage(unicode(img_path)).exif_thumbnail.as_blob() if thumb: logger.debug("Using EXIF thumbnail for {0}".format(img_path)) return thumb else: logger.debug("Generating thumbnail for {0}".format(img_path)) return scale_image(unicode(img_path), width=160)
def create_thumbnail(url, fp, width, height): blob = requests.get(url).content image = JPEGImage(blob=blob) """Check if downscaling image is possible with requested width and height. """ if image.width < width: width = width/2 if image.height < height: height = height/2 image.downscale(width, height, 90).save(fp) with open(fp, 'r') as f: thumbnail = f.read() return thumbnail
def get_thumbnail(img_path): """ Return thumbnail for image. :param img_path: Path to image :type img_path: pathlib.Path :return: The thumbnail :rtype: bytestring """ if HAS_JPEGTRAN and img_path.suffix.lower() in ('.jpg', '.jpeg'): img = JPEGImage(unicode(img_path)) thumb = img.exif_thumbnail if thumb: logger.debug("Using EXIF thumbnail for {0}".format(img_path)) return thumb.as_blob() logger.debug("Generating thumbnail for {0}".format(img_path)) return scale_image(img_path, width=160)
def crop_image(fname, left, top, width=None, height=None): if HAS_JPEGTRAN: img = JPEGImage(fname) else: img = Image(filename=fname) width = (img.width - left) if width is None else width height = (img.height - top) if height is None else height if width > img.width: width = img.width if height > img.height: width = img.height logger.debug("Cropping \"{0}\" to x:{1} y:{2} w:{3} h:{4}".format( fname, left, top, width, height)) cropped = img.crop(left, top, width=width, height=height) if HAS_JPEGTRAN: cropped.save(fname) else: img.save(filename=fname)
def scale_image(img_path, width=None, height=None): def get_target_size(srcwidth, srcheight): aspect = srcwidth / srcheight target_width = width if width else int(aspect * height) target_height = height if height else int(width / aspect) return target_width, target_height if width is None and height is None: raise ValueError("Please specify either width or height") if HAS_JPEGTRAN and img_path.suffix.lower() in ('.jpg', '.jpeg'): img = JPEGImage(unicode(img_path)) width, height = get_target_size(img.width, img.height) return img.downscale(width, height).as_blob() else: with Image(filename=unicode(img_path)) as img: width, height = get_target_size(img.width, img.height) img.sample(width, height) return img.make_blob(format='jpg')
def capture(self, path): self.logger.info("Capturing image into '{0}'".format(path)) self.logger.debug(self.config['test'].get()) with Drawing() as draw: fpath = unicode(self._test_imgs[self.target_page]) with Image(filename=fpath) as img: draw.font_size = 240 draw.text(img.width / 2, img.height / 2, path.name) draw(img) img.save(filename=unicode(path)) img = JPEGImage(fname=unicode(path)) aspect = float(img.width) / img.height upside_down = self.config["upside_down"].get(bool) if self.target_page == 'odd': img.exif_orientation = 8 if upside_down else 6 else: img.exif_orientation = 6 if upside_down else 8 img.exif_thumbnail = img.downscale(320, int(320 / aspect)) img.save(unicode(path))
def callback(self, left_image, left_info, right_image, right_info): #flip image in lossless fashion #rospy.logwarn( "callback called") img = JPEGImage(blob=right_image.data) rotatedImg = img.flip('vertical') rotatedImg = rotatedImg.flip('horizontal') right_image.data = rotatedImg.as_blob() #self.stamp = (left_image.header.stamp + left_info.header.stamp + right_image.header.stamp + right_info.header.stamp)/4.0 self.stamp = rospy.Time.now() left_image.header.stamp = self.stamp left_info.header.stamp = self.stamp right_image.header.stamp = self.stamp right_info.header.stamp = self.stamp self.left_image_pub.publish(left_image) self.left_info_pub.publish(left_info) self.right_image_pub.publish(right_image) self.right_info_pub.publish(right_info)
def autorotate_image(in_path, out_path): """ Rotate an image according to its EXIF orientation tag. :param in_path: Path to image that should be rotated :type in_path: unicode :param out_path: Path where rotated image should be written to :type out_path: unicode """ img = JPEGImage(in_path) if img.exif_orientation is None: logger.warn( "Image {0} did not have any EXIF rotation, did not rotate.". format(in_path)) return elif img.exif_orientation in (0, 1): logger.info("Image {0} is already rotated.".format(in_path)) shutil.copyfile(in_path, out_path) else: rotated = img.exif_autotransform() rotated.save(out_path)
def capture(self, path): shoot_raw = self.config['shoot_raw'].get(bool) # TODO: support choosing jpg size # TODO: support choosing sraw vs raw # TODO: support capturing raw + jpeg # TODO: choose raw extension based on camera vendor extension = 'cr2' if shoot_raw else 'jpg' local_path = "{0}.{1}".format(path, extension) self._camera.capture_image(local_path) # Set EXIF orientation self.logger.debug("Setting EXIF orientation on captured image") img = JPEGImage(local_path) if self.target_page == 'odd': img.exif_orientation = 6 # -90° else: img.exif_orientation = 8 # 90° img.save(local_path)
def test_get_exif_thumbnail_no_compression(): thumb = JPEGImage(fname='test/test_thumb.jpg').exif_thumbnail assert thumb assert thumb.width == 196 assert thumb.height == 130
def image(): with open('test/test.jpg', 'rb') as fp: return JPEGImage(blob=fp.read())
os.chdir('images/' + ['RTTY', 'APRS', 'LORA0', 'LORA1', 'FULL'][i]) camera.downloadLastMedia(camera.take_photo(0)) os.chdir('../..') filename = 'convert_' + str(i) if os.path.isfile(filename): # Read and delete conversion file file = open(filename, 'r') lines = file.read().splitlines() file.close() if os.path.isfile('ssdv.jpg'): os.remove('ssdv.jpg') # resize selected image file image = JPEGImage(lines[3]) image.downscale(int(lines[4]), int(lines[5])).save('ssdv.jpg') # run SSDV conversion os.system('ssdv ' + lines[1] + ' -e -c ' + lines[0] + ' -i ' + lines[2] + ' ssdv.jpg ' + lines[6]) # Move all images that werre considered folder1 = "images/" + ['RTTY', 'APRS', 'LORA0', 'LORA1', 'FULL'][i] folder2 = folder1 + "/" + time.strftime("%d_%m_%y") if not os.path.isdir(folder2): os.mkdir(folder2) try: os.system("mv " + folder1 + "/*.JPG " + folder2) os.remove(filename) finally:
def update_exif_orientation(data, orientation): img = JPEGImage(blob=data) img.exif_orientation = orientation return img.as_blob()
def main(args=None): parser = OptionParser() parser.add_option("-i", "--input", dest="input", default=None, help='specify the path of the input bag file') parser.add_option("-o", "--output", dest="output", default=None, help='specify the path of the output bag file') parser.add_option("-r", "--do-not-rotate-right-camera", action="store_true", dest="doNotRotateRightCamera", default=False, help='specify to rotate right camera image stream') (options, args) = parser.parse_args(args=args) rosBagInPath = os.path.abspath(options.input) logger.info('Using input rosbag file: %s' % (rosBagInPath)) rosBagOutPath = os.path.abspath(options.output) logger.info('Using output rosbag file: %s' % (rosBagOutPath)) if options.doNotRotateRightCamera: logger.info( 'Image stream from right camera will not be rotated (vertically and horizontally)' ) nbTotalMessageProcessed = 0 with rosbag.Bag(rosBagOutPath, 'w') as outbag: with rosbag.Bag(rosBagInPath, 'r') as inbag: # Read all messages for topic, msg, timestamp in inbag.read_messages(): # Replace rosbag timestamps with the ones from the headers, if available if msg._has_header: timestamp = msg.header.stamp else: logger.warn( 'Topic %s provides messages than have no header: using timestamps from rosbag' % (topic)) # Rename topic of imu barometer sensor # NOTE: this is to properly handle the old topic name if topic == '/imu/baro': topic = '/imu/pressure' # Rotate right camera images (lossless) if topic == '/video/right/compressed' and not options.doNotRotateRightCamera: img = JPEGImage(blob=msg.data) rotatedImg = img.flip('vertical').flip('horizontal') msg.data = rotatedImg.as_blob() outbag.write(topic, msg, timestamp) nbTotalMessageProcessed += 1 elif msg.__class__.__name__.endswith('ImuBatch'): # Unbatch messages of type ImuBatch into individual Imu messages. # Use the timestamps from the individual messages. for m in unbatchImu(msg): outbag.write(topic, m, m.header.stamp) nbTotalMessageProcessed += 1 elif msg.__class__.__name__.endswith('MagneticFieldBatch'): # Unbatch messages of type MagneticFieldBatch into individual MagneticField messages. # Use the timestamps from the individual messages. for m in unbatchMagneticField(msg): outbag.write(topic, m, m.header.stamp) nbTotalMessageProcessed += 1 else: outbag.write(topic, msg, timestamp) nbTotalMessageProcessed += 1 if nbTotalMessageProcessed % 100 == 0: logger.info('Processed %d messages' % (nbTotalMessageProcessed)) logger.info('Processed %d messages' % (nbTotalMessageProcessed))
def update_exif_orientation(fpath, orientation): img = JPEGImage(fpath) img.exif_orientation = orientation img.save(fpath)
#pip install jpegtran-cffi from jpegtran import JPEGImage img = JPEGImage( '/home/ekmek/intership_project/video_parser_v1/_videos_to_test/RuzickaDataset/input/five/0001.jpg' ) import requests # JPEGImage can also be initialized from a bytestring #blob = requests.get("http://example.com/image.jpg").content #from_blob = JPEGImage(blob=blob) # Reading various image parameters print(img.width, img.height) # "640 480" print(img.exif_orientation) # "1" (= "normal") """ # If present, the JFIF thumbnail can be obtained as a bytestring thumb = img.exif_thumbnail # Transforming the image img.scale(320, 240).save('scaled.jpg') img.rotate(90).save('rotated.jpg') img.crop(0, 0, 100, 100).save('cropped.jpg') # Transformations can be chained data = (img.scale(320, 240) .rotate(90) .flip('horizontal') .as_blob())
def rotate_image(self, filename, data): img = JPEGImage(filename) try: img.exif_autotransform().save(filename) except: pass