Skip to content

Commit

Permalink
Add format conversion based on destination extension
Browse files Browse the repository at this point in the history
  • Loading branch information
jrrodri committed Apr 18, 2018
1 parent 5b889fc commit 2361f38
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 59 deletions.
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Python client for the [Abraia](https://abraia.me) API, used to smartly
transform and optimize (compress) images on-line. Read more at
[https://abraia.me/docs](https://abraia.me/docs).

Optimize images for web with no quality damage based on perception-driven
Optimize images for Web with no quality damage based on perception-driven
technology.

* Optimal image compression with our perceptual adjustment to preserve the
Expand All @@ -21,11 +21,17 @@ abraia optimize --width 800 --height 400 https://images.pexels.com/photos/700948

![Optimized and smart cropped skater](./images/skater.jpg)

[Original image by Willian Was from Pexels (Size: 4865x3321 | Weight: 10.1MB)](https://www.pexels.com/photo/f-s-flip-700948/)
The example takes an [image by Willian Was from Pexels](https://www.pexels.com/photo/f-s-flip-700948/)
with a size of 4865x3321 pixels and a weight of 10.1MB and automatically
generates a header of 800x400 pixels cropping, resizing, and optimizing the
image to directly be used on Web.

## Installation

Install the API client and CLI with a simple command:
The Abraia python client works in Windows, Mac, and Linux with Python 2 and 3
(python>=2.6.5).

Install the API client and the CLI with a simple command:

```
pip install -U abraia
Expand All @@ -39,7 +45,7 @@ abraia --version

## Configuration

For configuration you just need to [create an account](https://abraia.me/login)
For configuration you just need to [create a free account](https://abraia.me/login)
and introduce the API KEYS using the command bellow:

```
Expand All @@ -48,7 +54,7 @@ abraia configure

## Usage

API usage:
### API usage:

The fluent design of the Abraia API makes easy to compress and transform
images. You just need to define the source of the image, the transformation
Expand All @@ -58,12 +64,12 @@ operation, and the sink for the resultant image.
import abraia

abraia.from_file('images/lion.jpg').resize(
width=600, height=600).to_file('images/lion_600x600.jpg')
width=600, height=600).to_file('images/lion_600x600.jpg')
abraia.from_url('https://abraia.me/images/random.jpg').resize(
width=600, height=400).to_file('images/random_600x400.jpg')
width=600, height=400).to_file('images/random_600x400.jpg')
```

CLI usage:
### CLI usage:

With the CLI tool you can compress and optimize all the images in a folder with
a simple command:
Expand Down
8 changes: 3 additions & 5 deletions abraia/abraia.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import requests

from . import config
Expand Down Expand Up @@ -45,6 +46,8 @@ def from_url(self, url):
return self

def to_file(self, filename):
root, ext = os.path.splitext(filename)
self.params['fmt'] = ext.lower() if ext != '' else None
resp = session.get(self.url, params=self.params, stream=True)
if resp.status_code != 200:
raise APIError('GET {} {}'.format(self.url, resp.status_code))
Expand All @@ -60,11 +63,6 @@ def resize(self, width=None, height=None):
self.params['h'] = height
return self

def format(self, format=None):
if format:
self.params['fmt'] = format
return self

def analyze(self):
url = '{}/analysis'.format(config.API_URL)
if 'url' not in self.params:
Expand Down
87 changes: 42 additions & 45 deletions scripts/abraia
Original file line number Diff line number Diff line change
Expand Up @@ -53,29 +53,30 @@ def process_batch(args):
for filename in tqdm(filenames, unit='file'):
path, name = os.path.split(filename)
nam, ext = os.path.splitext(name)
ext = format if format is not None else ext
fileout = os.path.join(path, nam+'_o'+ext)
oext = format if format is not None else ext
fileout = os.path.join(path, nam+'_o'+oext)
if dirname:
relpath = os.path.relpath(path, dirname)
if not os.path.exists(os.path.join(dirname+'_o', relpath)):
os.makedirs(os.path.join(dirname+'_o', relpath))
fileout = os.path.join(dirname+'_o', relpath, nam+ext)
fileout = os.path.join(dirname+'_o', relpath, nam+oext)
if dest is not None:
fileout = dest
if ext.lower() in IMAGE_EXTS:
root, oext = os.path.splitext(fileout)
if ext.lower() in IMAGE_EXTS and oext.lower() in IMAGE_EXTS:
try:
abraia.from_file(filename).resize(
width=args.get('width'),
height=args.get('height')
).format(format).to_file(fileout)
height=args.get('height')).to_file(fileout)
except:
shutil.copy2(filename, fileout)
if format is None and os.path.getsize(fileout) > os.path.getsize(filename):
print(ext, oext)
if ext == oext and os.path.getsize(fileout) > os.path.getsize(filename):
shutil.copy2(filename, fileout)
sizein = os.path.getsize(filename) / 1024
sizeout = os.path.getsize(fileout) / 1024
tqdm.write('[{3:04.1f}%] {1:6.1f}KB -> {2:6.1f}KB ({0})'.format(
name, sizein, sizeout, 100 * (1 - sizeout / sizein)))
os.path.split(fileout)[1], sizein, sizeout, 100 * (1 - sizeout / sizein)))
else:
shutil.copy2(filename, fileout)
else:
Expand All @@ -85,13 +86,11 @@ def process_batch(args):
def process_url(args):
path = args['path']
dest = args.get('dest')
format = args.get('format')
fileout = os.path.split(path) if dest is None else dest
try:
abraia.from_url(path).resize(
width=args.get('width'),
height=args.get('height')
).format(format).to_file(fileout)
height=args.get('height')).to_file(fileout)
print('New image saved:', dest)
except:
print('Error to processing:', path)
Expand All @@ -104,9 +103,10 @@ def process_analyze(args):

def process_list():
json = abraia.list()
files = [(datetime.fromtimestamp(
f['date']), f['size'], f['name']) for f in json['files']]
txt = '\n'.join(['{} {:>7} {}'.format(*f) for f in files])
files = [(f['date'], f['size'], f['name']) for f in json['files']]
txt = '\n'.join(['{} {:>7} {}'.format(
datetime.fromtimestamp(f[0]), *f[1:]) for f in files])
txt += '\ntotal {}'.format(len(files))
print(txt)


Expand All @@ -115,30 +115,22 @@ def process_remove(args):


def parse_input():
parser = argparse.ArgumentParser(
description='Abraia image optimization tool')
parser.add_argument('-V', '--version', action='version', version='0.2.12')
subparsers = parser.add_subparsers(dest='command')
parser_configure = subparsers.add_parser(
'configure', help='configure the access keys')
parser_optimize = subparsers.add_parser(
'optimize', help='optimize the image or directory of images')
parser_optimize.add_argument(
'--width', type=int, help='resize to specified width')
parser_optimize.add_argument(
'--height', type=int, help='resize to specified height')
parser_optimize.add_argument(
'--format', type=str, help='convert to specified image format. Allowed output extensions: %s' % str(IMAGE_EXTS))
parser_optimize.add_argument(
'path', nargs='?', help='image path or directory to process')
parser_optimize.add_argument(
'dest', nargs='?', help='destination directory or image path')
parser_analyze = subparsers.add_parser(
'analyze', help='analyze the image or diretory of images')
parser_analyze.add_argument(
'path', nargs='?', help='image path or directory to process')
parser_list = subparsers.add_parser('ls', help='list stored files')
parser_remove = subparsers.add_parser('rm', help='remove a stored file')
parser = argparse.ArgumentParser(description='Abraia image optimization tool')
parser.add_argument('-V', '--version', action='version', version='0.2.13')
subparser = parser.add_subparsers(dest='command')
subparser.add_parser('configure', help='configure the access keys')
parser_optimize = subparser.add_parser('optimize', help='optimize an image or a directory of images')
parser_optimize.add_argument('--width', type=int, help='resize to specified width')
parser_optimize.add_argument('--height', type=int, help='resize to specified height')
parser_optimize.add_argument('--format', type=str, help='convert to specified image format. Allowed output extensions: %s' % str(IMAGE_EXTS))
parser_optimize.add_argument('path', nargs='?', help='image path or directory to process')
parser_optimize.add_argument('dest', nargs='?', help='destination directory or image path')
parser_analyze = subparser.add_parser('analyze', help='analyze an image or a diretory of images')
parser_analyze.add_argument('path', nargs='?', help='image path or directory to process')
parser_store = subparser.add_parser('store', help='work with the cloud stored files')
subparser_store = parser_store.add_subparsers(dest='subcommand')
subparser_store.add_parser('ls', help='list stored files')
parser_remove = subparser_store.add_parser('rm', help='remove a stored file')
parser_remove.add_argument('path', nargs='?', help='image path to remove')
args = vars(parser.parse_args())

Expand All @@ -153,10 +145,14 @@ def parse_input():
if args['path'] is None:
parser_analyze.print_help()
sys.exit()
elif args['command'] == 'rm':
if args['path'] is None:
parser_remove.print_help()
elif args['command'] == 'store':
if args['subcommand'] is None:
parser_store.print_help()
sys.exit()
elif args['subcommand'] == 'rm':
if args['path'] is None:
parser_remove.print_help()
sys.exit()
return args


Expand All @@ -167,10 +163,11 @@ def process_input(args):
process_batch(args)
elif args['command'] == 'analyze':
process_analyze(args)
elif args['command'] == 'ls':
process_list()
elif args['command'] == 'rm':
process_remove(args)
elif args['command'] == 'store':
if args['subcommand'] == 'ls':
process_list()
elif args['subcommand'] == 'rm':
process_remove(args)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='abraia',
version='0.2.12',
version='0.2.13',
description='Abraia Python SDK',
long_description=long_description,
long_description_content_type='text/markdown',
Expand Down

0 comments on commit 2361f38

Please sign in to comment.