paint-brush
Enhance Your Photos with the CSS Contrast, Brightness, Saturation, and Sepia Functionsby@ljaviertovar
1,532 reads
1,532 reads

Enhance Your Photos with the CSS Contrast, Brightness, Saturation, and Sepia Functions

by L Javier Tovar
L Javier Tovar HackerNoon profile picture

L Javier Tovar

@ljaviertovar

☕ Full Stack developer 👨‍💻 Indie maker ✍️ Tech writer

August 22nd, 2023
Read on Terminal Reader
Read this story in a terminal
Print this story
Read this story w/o Javascript
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Create custom Instagram filters using React and CSS. Adjust contrast, brightness, saturation, apply the sepia effect or convert images to grayscale.
featured image - Enhance Your Photos with the CSS Contrast, Brightness, Saturation, and Sepia Functions
1x
Read by Dr. One voice-avatar

Listen to this story

L Javier Tovar HackerNoon profile picture
L Javier Tovar

L Javier Tovar

@ljaviertovar

☕ Full Stack developer 👨‍💻 Indie maker ✍️ Tech writer

Learn More
LEARN MORE ABOUT @LJAVIERTOVAR'S
EXPERTISE AND PLACE ON THE INTERNET.
0-item
1-item
2-item

STORY’S CREDIBILITY

Guide

Guide

Walkthroughs, tutorials, guides, and tips. This story will teach you how to do something new or how to do something better.

Code License

Code License

The code in this story is for educational purposes. The readers are solely responsible for whatever they build with it.

DYOR

DYOR

The writer is smart, but don't just like, take their word for it. #DoYourOwnResearch before making any investment decisions or decisions regarding your health or security. (Do not regard any of this content as professional investment advice, or health advice)


Nowadays, many applications help us to edit our photos and images. With these applications, we can add some artistic effect or a filter that makes our image look with better color or maybe without color or look like an old photo, etc.


Apps such as Instagram offer editing options with many predefined filters and the option to create one by ourselves. This makes me wonder: “How do filters work on digital images? How are they created, or what do they do to the image?”.


I’m not going to address issues such as image processing with graphics or algorithms, but I would like to develop an application that allows us to add filters to an image.

Using web technologies and a cool repository, I found we will develop a clone of the Instagram filters.


What is a filter on an image?

A filter is a mathematical equation (called a convolution product) that allows modifying the value of a pixel according to the values of contiguous pixels, with coefficients for each pixel in the region to which it is applied.


Different objectives:


  • Smooth the image: reduce intensity variations between neighboring pixels.

  • Eliminate noise: modify those pixels whose intensity level is very different from that of their neighbors.

  • Enhance the image: increase intensity variations where they occur.

  • Detect edges: detect those pixels where there is an abrupt change in the intensity function.


The CSS Filter property

The CSS filter property provides graphical effects such as blurring or color change in the rendering before the element is displayed. Filters are commonly used to adjust the rendering of images, backgrounds, or borders.


The functions that we will use of this property to create our filters are:


contrast(): This is the difference in light intensity between the black and white tones of the image. High contrasts darken shadows and dark tones more, making whites brighter, while low contrasts decrease the intensity of both ranges.


brightness(): The attribute of a visual sensation whereby an area appears to show more or less light.


saturate(): It is the intensity of each color in a photo according to its composition’s degree of white, black, or gray. The more absence of these on a color, the more purity and intensity. And the more it is mixed with gray, the less saturation.


sepia(): A sepia image is a black-and-white image that has a warm brown tone. Sepia tints can make an image look older.


grayscale(): Grayscale is a range of monochrome shades of black to white. Therefore, a grayscale image contains only shades of gray and no color.


Time to Code

As I mentioned before, we will use Instagram.css, which is like a CSS class library that provides us with filters very similar to Instagram’s. You can find the repository and demo of the application we will develop at the end of the tutorial.

Setting Up

We create our application with the following command:


npx create-react-app myApp


We install the dependencies that we will need in the project:


npm i react-slick slick-carousel rc-slider styled-components react-icons


After that, we create the following structure for the project:


src/
├── assets/
│   ├── fonts
│   └── img
├── components/
│   ├── CustomFilter.jsx
│   ├── CustomFilterOptions.jsx
│   ├── Filter.jsx
│   ├── ImgWrapper.jsx
│   ├── NormalFilter.jsx
│   └── Title.jsx
├── pages/
│   └── Home.js
├── styles/
│   └── GlobalStyles.js
│   ├── instagram.min.css
│   └── Typography.js
├── App.js
└── index.js


As you can see, it will be a simple application where what we want to review is how to add the CSS classes to our previously added image in the assets/img folder.

Also, develop functionalities with which we will be able to create a customized filter.


Components

Home.jsx: It is the root component, where we will create a couple of states which will allow us to know which filter is selected at the moment and thus apply it to our main image.


It also has a state that will be responsible for saving the custom filters that the user will select through the range of Sliders that we are going to create.


Home.jsx

Home.jsx


Filters.jsx: In this component, we import the file instagram.min.css and we map the names of the classes that the library offers us. I have created a JSON object which contains all the available classes.


const filters = [
  { name: 'Aden', class: 'filter-aden'},
  { name: 'Amaro', class: 'filter-amaro'},
  { name: 'Ashby', class: 'filter-ashby'},
  { name: 'Brannan', class: 'filter-brannan'}
  ...
]


Now with the filters in an object, we will make a map and create for each element a card with the image we want to edit, adding the corresponding class to give a preview of the added effect.

In addition to that with the react-slick library, we have created a Slider so we can visualize all the elements.


import React, { useEffect } from 'react'
import styled from 'styled-components'
import Slider from 'react-slick'

import thumbnail from '../assets/img/img1.jpg'

import '../styles/instagram.min.css'
import 'slick-carousel/slick/slick.css'
import 'slick-carousel/slick/slick-theme.css'

const FiltersStyles = styled.div`
  width: 70%;
  margin: auto;
  .slick-prev:before {
    color: var(--blue-1);
  }
  .slick-next:before {
    color: var(--blue-1);
  }
`
const Filters = ({ filterClass, setFilterClass, imgRef }) => {
  useEffect(() => {
    const divImg = imgRef.current
    divImg.style.filter = ''
  }, [filterClass])

  const filters = [
    {
      name: 'Aden',
      class: 'filter-aden',
    },
    {
      name: 'Amaro',
      class: 'filter-amaro',
    },
    {
      name: 'Ashby',
      class: 'filter-ashby',
    },
  ]

  const settings = {
    dots: false,
    Infinite: true,
    speed: 500,
    slidesToShow: 5,
    slidesToScroll: 5,
  }

  return (
    <FiltersStyles>
      <Slider {...settings}>
        {filters.map((filter, index) => {
          return (
            <div key={index}>
              <div
                className={`filter-item ${
                  filterClass === filter.class ? 'filter-item--selected' : ''
                }`}
                onClick={() => setFilterClass(filter.class)}
              >
                <div className="filter-item__img">
                  <img
                    className={filter.class}
                    src={thumbnail}
                    alt={filter.name}
                  />
                </div>
                <div className="filter-item__name">
                  <p>
                    <strong>{filter.name}</strong>
                  </p>
                </div>
              </div>
            </div>
          )
        })}
      </Slider>
    </FiltersStyles>
  )
}

export default Filters


Slider whit all filters

Slider whit all filters


CustomFilterOptions.jsx: In this component, we try to create controls that allow us to create our effect. For this case, we use the CSS Filter property, which provides us with several interesting functions.


So that our app is more similar to the controls of the already existing applications, I have used the rc-slider library with which we will create ranges of values with which each function of the Filter property works.


We will create a state and initialize it with the starting value of each effect. Using the Sliders, we will save each newly selected value with the onChange property of each component.


Finally, we have a function that we call setCustomFilterClass with which we will create our CSS style starting from the values of each effect that we create and if we assign it to our main image.

With this, the effect will be created in our image.


import React, { useState } from 'react'
import Slider, { SliderTooltip } from 'rc-slider'
import styled from 'styled-components'

import 'rc-slider/assets/index.css'

const CustomFilterOptionsStyles = styled.div`
  .customFilters-container {
    width: 400px;
    margin-right: 100px;
  }
  .customFilters-item {
    margin: 3rem 0;
    display: flex;
    gap: 1rem;
    align-content: center;
    p {
      width: 160px;
    }
  }
`

const CustomFilterOptions = ({ imgRef }) => {
  const [contrast, setContrast] = useState(100)
  const [brightness, setBrightness] = useState(100)

  const { Handle } = Slider

  const handle = props => {
    const { value, dragging, index, ...restProps } = props

    return (
      <SliderTooltip
        prefixCls="rc-slider-tooltip"
        overlay={`${value} %`}
        visible={true}
        placement="top"
        key={index}
      >
        <Handle value={value} {...restProps} />
      </SliderTooltip>
    )
  }

  const onChangeContrast = value => {
    setContrast(value)
    setCustomFilterClass()
  }

  const onChangeBrightness = value => {
    setBrightness(value)
    setCustomFilterClass()
  }

  const setCustomFilterClass = () => {
    const style = `contrast(${contrast}%) brightness(${brightness}%) saturate(${saturate}%) sepia(${sepia}%) grayScale(${gray}%)`

    const divImg = imgRef.current
    divImg.style.filter = style
  }

  return (
    <CustomFilterOptionsStyles>
      <div className="customFilters-container">
        <div className="customFilters-item">
          <p>Contrast</p>
          <Slider
            step={1}
            min={0}
            max={200}
            defaultValue={contrast}
            handle={handle}
            onChange={onChangeContrast}
          />
        </div>
        <div className="customFilters-item">
          <p>Brightness</p>
          <Slider
            step={1}
            min={0}
            max={200}
            defaultValue={brightness}
            handle={handle}
            onChange={onChangeBrightness}
          />
        </div>
      </div>
    </CustomFilterOptionsStyles>
  )
}

export default CustomFilterOptions


Custom filter

Custom filter


That’s it! We have created an application with which we can assign Instagram-like effects to any image we want, in addition to being able to create our custom effect.


See the demo here

Project repo here

Conclusion

In this tutorial, we tried to simulate the operation of applications that edit images by adding filters or effects to them, in this case, Instagram-like filters.


Although this application can still be improved and add many other basic features that these types of apps have, we have developed the part that interested us about the filters.

I hope you had fun developing this app as I did and that you can add these features to any project that comes your way.




Read more:



Want to connect with the Author?

Love connecting with friends all around the world on Twitter.


Also published here.

L O A D I N G
. . . comments & more!

About Author

L Javier Tovar HackerNoon profile picture
L Javier Tovar@ljaviertovar
☕ Full Stack developer 👨‍💻 Indie maker ✍️ Tech writer

TOPICS

THIS ARTICLE WAS FEATURED IN...

Permanent on Arweave
Read on Terminal Reader
Read this story in a terminal
 Terminal
Read this story w/o Javascript
Read this story w/o Javascript
 Lite
Ljaviertovar
X REMOVE AD