What are the steps to add SVG effects to an image or div element?

Embarking on my first venture into using SVG graphics has left me feeling a bit bewildered. Despite extensive research, I have yet to stumble upon the answer to my current quandary.

The objective at hand is to transform an image, assuming that the source image is colored, into the following appearance:

https://i.sstatic.net/pS9q7.jpg

The primary motivation for this effect stems from the need to rectify poor-quality images (both aesthetically and resolution-wise) that clients may upload onto their websites.

In Photoshop, achieving this outcome involves utilizing Gradient Map alongside a transparent grid in Mode Multiply.

While I've been successful in applying a filter for grayscale and "gradient map," integrating the grid/pattern remains a challenge.

Here's the progress of my code thus far:

SVG file titled gradient-map.svg

<svg xmlns="http://www.w3.org/2000/svg">
   <filter id="duotone_filter">
      <feColorMatrix type="matrix" result="grayscale"
         values="1 0 0 0 0
                 1 0 0 0 0
                 1 0 0 0 0
                 0 0 0 1 0" >
      </feColorMatrix>
      <feComponentTransfer color-interpolation-filters="sRGB" result="duotone">
        <feFuncR type="table" tableValues="0.0039525691 0.5764705882"></feFuncR>
        <feFuncG type="table" tableValues="0.0123456790 0.8431372549"></feFuncG>
        <feFuncB type="table" tableValues="0.0123456790 0.9803921569"></feFuncB>
        <feFuncA type="table" tableValues="0 1"></feFuncA>
     </feComponentTransfer>
  </filter>        
</svg>

HTML snippet

<div class="image">
    <img src="link/to/file" />
</div>

CSS styling

.image {
   filter: url('../images/gradient-map.svg#duotone_filter');
}

Also, here's the SVG template for the pattern/fill:

<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="6px" height="6px" viewBox="0 0 6 6">
   <circle cx="3" cy="3" r="2" />
</svg>

Is this the correct approach? How should I proceed in order to achieve the desired effect?

If you could redirect me to any valuable resources, I would be immensely grateful. I seem to be struggling to find up-to-date guides or articles.

Thank you.

Answer №1

Looks like you're making progress in the right direction. I've created a demo for you to check out, which you can find on Codepen. Here's what the output looks like:

https://i.sstatic.net/zK3Xm.jpg

If you need some guidance, there's a great question about how to Overlay grid on responsive image. In my example, I chose to overlay and scale a large transparent PNG instead of using a repeating grid section. Feel free to customize the color, size, and other attributes of your grid overlay according to your preferences.

Note that you can't use pseudo-elements like :after or :before directly with img elements. You'll have to wrap them in a container, or you could use an additional element as shown below:

<div class="img-container">
    <img src="..." />
    <div class="grid-overlay"></div>
</div>

However, personally, I prefer using pseudo-elements to avoid repeating

<div class="grid-overlay"></div>
every time I want to add a grid overlay.

img {
  filter: url(#duotone_filter)
}

.img-container {
  display: inline-block;
  overflow: hidden;
  position: relative;
  height: 375px;
}

.img-container::after {
  content: '';
  display: block;
  position: absolute;
  background-image: url('http://www.freeiconspng.com/uploads/grid-png-31.png');
  background-size: 100%;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
<div class="img-container"><img src="http://kb4images.com/images/random-image/37670495-random-image.jpg" /></div>

<svg xmlns="http://www.w3.org/2000/svg">
   <filter id="duotone_filter">
      <feColorMatrix type="matrix" result="grayscale"
         values="1 0 0 0 0
                 1 0 0 0 0
                 1 0 0 0 0
                 0 0 0 1 0" >
      </feColorMatrix>
      <feComponentTransfer color-interpolation-filters="sRGB" result="duotone">
        <feFuncR type="table" tableValues="0.0039525691 0.5764705882"></feFuncR>
        <feFuncG type="table" tableValues="0.0123456790 0.8431372549"></feFuncG>
        <feFuncB type="table" tableValues="0.0123456790 0.9803921569"></feFuncB>
        <feFuncA type="table" tableValues="0 1"></feFuncA>
     </feComponentTransfer>
  </filter>        
</svg>

Here's another example that utilizes only SVGs (symbols):

https://i.sstatic.net/tPJ9l.png

Lastly, check out this final example that includes two SVG filters and works well in Firefox. The crux of this example lies in using an additional filter to create a composite image. While I used an external SVG in this instance, you can also utilize an inline SVG and reference it by ID.

<filter id="overlay">
    <feImage result="sourceTwo" xlink:href="http://www.vectorstash.com/vectors/vectorstash-grid.svg" width="500" height="375" preserveAspectRatio="none" x="0" y="0" />
    <feComposite in="SourceGraphic" in2="sourceTwo" operator="out" x="0" y="0" />
  </filter>

Answer №2

To streamline the process, you can merge the grid overlay with the filter by incorporating inline SVG for the grid using an feImage primitive.

(I also made adjustments to your grayscale matrix because it previously only utilized the red channel as a source, which could lead to odd outcomes when working with photos heavy on blue or green tones.)

.filterclass {
    filter: url(#duotone_filter);
}
<svg xmlns="http://www.w3.org/2000/svg">
   <filter id="duotone_filter" color-interpolation-filters="sRGB" x="0%" y="0%" width="100%" height="100%">
      <feImage width="6" height="6" xlink:href= "data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20x%3D%220%22%20y%3D%220%22%20width%3D%226px%22%20height%3D%226px%22%20viewBox%3D%220%200%206%206%22%3E%0A%20%20%20%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%226%22%20height%3D%226%22%20fill%3D%22none%22%20stroke%3D%22grey%22/%3E%0A%3C/svg%3E"/>
      <feTile result="overlay"/>


      <feColorMatrix in="SourceGraphic" type="matrix" result="grayscale"
         values=".33 .33 .33 0 0
                 .33 .33 .33 0 0
                 .33 .33 .33 0 0
                 0 0 0 1 0" />

      <feComponentTransfer result="duotone">
        <feFuncR type="table" tableValues="0.0039525691 0.5764705882"></feFuncR>
        <feFuncG type="table" tableValues="0.0123456790 0.8431372549"></feFuncG>
        <feFuncB type="table" tableValues="0.0123456790 0.9803921569"></feFuncB>
        <feFuncA type="table" tableValues="0 1"></feFuncA>
     </feComponentTransfer>
    <feBlend mode="multiply" in="overlay"/>
  </filter>        
</svg>

<div >
<img class="filterclass" src="http://kb4images.com/images/random-image/37670495-random-image.jpg" />
</div>

The provided SVG for the inlined data uri is

    <svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="6px" height="6px" viewBox="0 0 6 6">
   <rect x="0" y="0" width="6" height="6" fill="none" stroke="grey"/>
</svg>

If you wish to make modifications, I recommend utilizing this svg+xml converter - here's the link: https://codepen.io/yoksel/details/JDqvs

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The images are not clickable when trying to hyperlink them

I'm attempting to create a clickable image that will redirect users to another site when clicked. Here's the code I've tried: <div class="haus"> <a href="http://google.com"><img src="http://schwedenladen.de/wp-content/the ...

The functionality of HTML5 Camera is experiencing issues while being used with Tomcat7

My Angular2 project includes HTML5 camera access functionality. I launch the project using Angular CLI (ng serve), which starts the web container for testing purposes. When trying to access the camera, the browser prompts me for permission. Once granted, e ...

What is the best way to center and personalize slider arrow placements vertically?

I applied CSS to customize the appearance of the previous and next arrows for .customer-logos, but I'm still seeing the default button style along with my changes. How can I resolve this issue and position the buttons on either side of the slider inst ...

A guide on choosing a custom button color and automatically reverting to its original color when another button is clicked

I have a collection of 24 buttons, all in a dark grey (#333333) shade. Whenever I click on one of the buttons, it changes to a vibrant blue color (#0099ff), which is functioning correctly. However, when I proceed to click on another button, the previous ...

Creating dynamic templates for table rows in AngularJS directives

Is it possible to dynamically load an AngularJS Directive templateUrl while working within a table? In my scenario, I have the following HTML structure where I am repeating a tr element with a fw-rule directive: <tbody> <tr ng-repeat="rule in ...

send data to a hyperlink

I need to pass a parameter to the href based on the first name in the list. The names are links to another page that I retrieve via an _id passed in the URL. The issue I am facing is that the id is not being passed to the URL, resulting in an error. How ...

Utilizing Angularjs for dynamic data binding in HTML attributes and style declarations

Can someone help me figure out how to use an AngularJS model as the value for an HTML attribute? For example: <div ng-controller="deviceWidth" width={{width}}> </div> Additionally, how can I achieve this within <style> markup? Where ...

Issues encountered when incorporating personalized CSS into a Vuetify element

Working with the Vuetify selector input component, v-select, and wanting to customize its style led me to inspecting it in Chrome and copying down the necessary classes. For instance, to change the font size of the active value, I utilized: .v-select__sel ...

Using SVG in a Vue standalone script without the need for a build step is easy with the

When I attempt to utilize Vue as a standalone script in an HTML file, my inline svg icons are rendered as solid filled squares instead of their intended shapes. This issue persists when using both Vue 2 and Vue 3 as standalone scripts. Although there are ...

Map region indicator tooltip

I possess a map that contains a specific area with a title. Here is the accompanying code: <map name="Map" id="Map"> <area alt="" shape="rect" coords="127,52,186,71" href="#" title="Extending telephone lines to other Egyptian governorates ...

React powered interactive tables

I am in the process of creating a dynamic table using React, and here is the data structure I am working with: { numRows: 2, numCols: 3, cells: [ { id: 1, pos: { row: 1, col: 1 }, content: 'This is th ...

Allowing the contenteditable attribute to function only on a single line of

My app allows users to create different lists, with the ability to edit the name. However, I am facing an issue where if a user types a new name, it should remain on only one line. I tried adding max height and overflow hidden properties, but it only hides ...

Issues with HTML5 video playback have been reported in both Chrome and Firefox browsers

I'm having trouble getting the following HTML5 Video code to work. Can someone help me spot what I might be missing? <video width="267" poster="Poster.gif" height="209"> <source src="6Minutes_1.mp4" type="video/mp4"></source> <so ...

How can I resize an element using jQuery resizable and then revert it back to its original size with a button click?

I need help figuring out how to revert an element back to its original size after it has been modified with .resizable. I attempted the following: <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="//code. ...

Confirm that the phone number is in the correct format using HTML

Hello, I am attempting to validate a phone number using the following format: 080******** 081******** 082******** 083******** I have tried the following code: <input type="tel" name="signupMobileTel" placeholder="08121234567" size=11 pattern="/^(08( ...

What is the best way to perform calculations within a PHP loop for <input> elements and then display the results using a JavaScript loop?

Hello everyone, I'm currently struggling with displaying the calculations from a loop of input tags. What I'm trying to achieve is having 5 rows with input fields. At the end of each row, there should be a span area that displays the calculation ...

JavaScript tag filtering system: Display only the div elements that contain all the specified classes in an array; otherwise, hide them

Can you provide some guidance on accomplishing this task? I am looking to toggle the visibility of a div based on its classes and an array. If the array contains the term something, then only divs with the class something will be displayed. If the array ...

JavaScript and jQuery experiencing difficulty rendering proper style and image in output display

I am currently working on code that extracts information from a JSON variable and displays it on a map. The code looks like this: marker.info_window_content = place.image + '<br/>' +"<h4>" + place.name + "</h4> ...

Conducting various calculations and showcasing them all on a single webpage

Uncertain about what to name this, but let's see if you understand my question. I have a table on a standard HTML page and I am performing some calculations using Javascript/jQuery. Example: function addThem() { var result; result = userIn ...

Inconsistency in div height caused by positioning disparities

My demonstration shows two lines that should appear equal in height, but one ends up looking thicker due to its top position. Even just adjusting the top position by 1px can make a significant difference in how they look. Is there any way to prevent this u ...