DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Enhancing Code Clarity With Python Namedtuples
  • What Is Pydantic?
  • Pydantic: Simplifying Data Validation in Python
  • Bridging Graphviz and Cytoscape.js for Interactive Graphs

Trending

  • Apache Spark 4.0: Transforming Big Data Analytics to the Next Level
  • Security by Design: Building Full-Stack Applications With DevSecOps
  • Tired of Spring Overhead? Try Dropwizard for Your Next Java Microservice
  • How To Build Resilient Microservices Using Circuit Breakers and Retries: A Developer’s Guide To Surviving
  1. DZone
  2. Data Engineering
  3. Data
  4. Add a Border to Your Photos With Python

Add a Border to Your Photos With Python

Learn how you can use your programming skills to bring out your inner photographer, and enhance the look of your site via photo editing.

By 
Mike Driscoll user avatar
Mike Driscoll
·
Oct. 30, 17 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
13.4K Views

Join the DZone community and get the full member experience.

Join For Free

sometimes it's fun to add a simple border to your photos. the pillow package has a very easy method of adding such borders to your images via its imageops module. as usual, you will need to have pillow installed to do any of the examples in this article. if you don't have it already, you can install it with pip:

pip install pillow

now that we've taken care of that bit of housekeeping, let's learn how to add a border!

adding a border

the focus of this article will be on using the imageops module to add our borders. for this example, we will use this photo of a neat butterfly i took. let’s write some code!

from pil import image, imageops
 
 
def add_border(input_image, output_image, border):
    img = image.open(input_image)
 
    if isinstance(border, int) or isinstance(border, tuple):
        bimg = imageops.expand(img, border=border)
    else:
        raise runtimeerror('border is not an integer or tuple!')
 
    bimg.save(output_image)
 
if __name__ == '__main__':
    in_img = 'butterfly.jpg'
 
    add_border(in_img, output_image='butterfly_border.jpg',
               border=100)

in the code above, we create a function that can accept three arguments:

  • the input image path.
  • the output image path.
  • the border, which can be an integer or a tuple of up to 4 integers representing pixels for each of the four sides of the image.

we open the input image and then we check the border's type. is it an int or a tuple or something else? if it's one of the first two, we add our border by calling the expand() function. otherwise, we raise an error because we passed in an invalid type. finally, we save the image. this is the result i got:

as you can see, when you just pass an integer in as your border, it applies to all four sides of the image. if we want the border on the top and bottom to be different then the right and left, we need to specify that. let's update the code and see what happens!

from pil import image, imageops


def add_border(input_image, output_image, border):
    img = image.open(input_image)

    if isinstance(border, int) or isinstance(border, tuple):
        bimg = imageops.expand(img, border=border)
    else:
        raise runtimeerror('border is not an integer or tuple!')

    bimg.save(output_image)

if __name__ == '__main__':
    in_img = 'butterfly.jpg'

    add_border(in_img,
               output_image='butterfly_border_top_bottom.jpg',
               border=(10, 50))

here we want to add a 10-pixel border to the left and right sides and a 50-pixel border to the top and bottom of the image. if you run this code, you should get the following result:

now let’s try specifying different values for all four sides!

from pil import image, imageops
 
 
def add_border(input_image, output_image, border):
    img = image.open(input_image)
 
    if isinstance(border, int) or isinstance(border, tuple):
        bimg = imageops.expand(img, border=border)
    else:
        raise runtimeerror('border is not an integer or tuple!')
 
    bimg.save(output_image)
 
if __name__ == '__main__':
    in_img = 'butterfly.jpg'
 
    add_border(in_img,
               output_image='butterfly_border_all_different.jpg',
               border=(10, 30, 20, 50))

in this example, we tell pillow that we want a border where the left side is 10-pixels, the top is 30-pixels, the right is 20-pixels and the bottom is 50-pixels wide. when i ran this code, i got this:

frankly, i don't know why you would want all four sides to have a different size border, but if you do, it's easy to apply.

changing the border color

you can also set the color of the border that you're adding. the default was obviously black. the pillow package supports specifying colors via "#rgb" (i.e. "#ff0000" for red), "rgb (red, green, blue)" where the rgb values are integers between 0 and 255, hsl values or html color names. let's update our code and add some color to our border:

from pil import image, imageops


def add_border(input_image, output_image, border, color=0):
    img = image.open(input_image)

    if isinstance(border, int) or isinstance(border, tuple):
        bimg = imageops.expand(img, border=border, fill=color)
    else:
        raise runtimeerror('border is not an integer or tuple!')

    bimg.save(output_image)

if __name__ == '__main__':
    in_img = 'butterfly.jpg'

    add_border(in_img,
               output_image='butterfly_border_indianred.jpg',
               border=100,
               color='indianred')

you will note that we added a new parameter here that specifies the color we want our border to be. the default is black, which is zero (0). in this example, we pass in the html color 'indianred'. here is the result:

you could get the same effect by changing the passed in value from 'indianred' to '#cd5c5c'.

just for fun, try changing the value you pass in to 'rgb(255,215,0)', which is a gold color. if you do, you can get your border to look like this:

note that you could also pass in 'gold', 'gold' or '#ffd700' and it would have resulted in the same color.

wrapping up

at this point, you should know how to add simple borders to your photos. as you've seen, you can change the number of pixels of border color for each side individually or for pairs or even for all four sides simultaneously. you can also change the color of the border to pretty much any color under the sun. take some time to play around with the code and see what you can come up with!

Python (language) Pass (software) IT Data Types Tuple Gold (linker)

Published at DZone with permission of Mike Driscoll, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Enhancing Code Clarity With Python Namedtuples
  • What Is Pydantic?
  • Pydantic: Simplifying Data Validation in Python
  • Bridging Graphviz and Cytoscape.js for Interactive Graphs

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!