<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: dev::unfiltered</title>
    <description>The latest articles on DEV Community by dev::unfiltered (@devunf).</description>
    <link>https://dev.to/devunf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3588%2F9056c648-c78f-4d4f-a868-67279f0cf2de.png</url>
      <title>DEV Community: dev::unfiltered</title>
      <link>https://dev.to/devunf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devunf"/>
    <language>en</language>
    <item>
      <title>Save your favorite dev.to posts offline!</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Fri, 22 Jan 2021 14:00:22 +0000</pubDate>
      <link>https://dev.to/devunf/save-your-favorite-dev-to-posts-offline-45nb</link>
      <guid>https://dev.to/devunf/save-your-favorite-dev-to-posts-offline-45nb</guid>
      <description>&lt;p&gt;&lt;em&gt;It takes too much time to copy-paste &amp;amp; then edit the blog I like on devto&lt;/em&gt;&lt;br&gt;
~ Me to Myself&lt;/p&gt;

&lt;p&gt;As a developer, I love reading plenty of blogs on &lt;a href="https://dev.to/"&gt;dev.to&lt;/a&gt; but prefer to save it on my machine. This has its perks which I will list down for you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When I read a blog, I want to edit some of the content as per my wish without affecting the original content on the same page itself. This edited content I prefer to save on my local machine so I can view it later. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When I have no network connection, I can read the blogs on my machine easily. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The best thing, this will be super &lt;strong&gt;productive&lt;/strong&gt; for you to save the content the way you like and read it when you want.&lt;/p&gt;

&lt;p&gt;To make you believe how useful and easy it's let's see the small demo before moving further: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi5yj331xdnjwlq52rrlj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi5yj331xdnjwlq52rrlj.gif" alt="demo" width="600" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have pretty good knowledge of javascript and DOM. With that knowledge, I just came up with a method to go to the particular blog which I enjoyed reading and focus on editing the blog while removing other elements such as navbar, footer, and others.&lt;/p&gt;

&lt;p&gt;It's quite simple you just need to edit the CSS properties of the elements using DOM. You can certainly do this on your own as well however I have made that job easier for you by collecting all the tags within the HTML whose CSS properties we want to change!&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisities
&lt;/h2&gt;

&lt;p&gt;Just open your console in your favorite browser and simply copy-paste the javascript DOM code. It's this easy!&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's remove the surrounding elements of the blog! ⚒️
&lt;/h2&gt;

&lt;p&gt;It's time to get to work, thus we will first remove the surrounding elements around the blog that you enjoyed reading and want to save on your machine! &lt;/p&gt;

&lt;p&gt;By surrounding elements, I mean user profile, navbar, footer, comment section, the moderator badge, and every other element which doesn't involve the contents of the blog.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div.crayons-article-actions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div.spec__tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div.crayons-article__subheader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;section#comments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;section.crayons-card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aside.crayons-layout__sidebar-right&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;footer.crayons-footer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;moderatorTag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.mod-actions-menu-btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moderatorTag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moderatorTag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the only list of tags that come under surrounding elements for the blog! Now after you have included this code in your console, just include 3 more lines to remove all of them!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila! All the surrounding elements have disappeared. 💨&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's edit the content as per our liking! ✍🏻
&lt;/h2&gt;

&lt;p&gt;This is the main part where you get the power to edit the content of the blog without affecting the original blog. In this, you just have to include one line in your console then you can edit the content on the page as you wish.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contenteditable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Time to save the contents on our machine 💽
&lt;/h2&gt;

&lt;p&gt;After you've completed editing the blog content, you want to save it as a pdf on your local machine. We can do this with a simple &lt;code&gt;window.print()&lt;/code&gt; however this might clip off some content. &lt;/p&gt;

&lt;p&gt;We want to save our content in the most accurate way possible thus we got to edit further properties of the &lt;code&gt;body&lt;/code&gt; tag. For this, include in your console the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;border&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;static&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;margin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px 5%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you've added this, you just got to add &lt;code&gt;window.print()&lt;/code&gt; &amp;amp; save it as a pdf on your local machine.&lt;/p&gt;

&lt;p&gt;One more query would arise that I have to always copy-paste the code and the answer to that is obviously a big NO! Just create a simple function as shown here, add it to your local storage as shown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanAndEdit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div.crayons-article-actions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div.spec__tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div.crayons-article__subheader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;section#comments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;section.crayons-card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aside.crayons-layout__sidebar-right&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;footer.crayons-footer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;moderatorTag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.mod-actions-menu-btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moderatorTag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moderatorTag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// editing content on the page&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contenteditable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// for printing content accurately&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;border&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;static&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;margin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px 5%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;editable-dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanAndEdit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've done this within the console, you can re-use this function any time you want by doing as followed in the console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;editable-dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;cleanAndEdit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, you can edit the content and save it with the method already discussed!&lt;/p&gt;

&lt;p&gt;I hope you enjoyed saving your most loved blog content on your machine based on your edits! You can refer to this code on &lt;a href="https://github.com/devunf/devto-clean-and-end"&gt;Github&lt;/a&gt; as well. Till then enjoy reading and continue learning. ✨&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A simplified notion on Image Processing</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Thu, 21 Jan 2021 13:34:32 +0000</pubDate>
      <link>https://dev.to/devunf/getting-familiarized-with-image-processing-its-implementation-using-pil-2j9a</link>
      <guid>https://dev.to/devunf/getting-familiarized-with-image-processing-its-implementation-using-pil-2j9a</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;b&gt;Digital image processing&lt;/b&gt; is the use of a &lt;a href="https://en.wikipedia.org/wiki/Computer#Digital_computers" rel="noopener noreferrer"&gt;digital computer&lt;/a&gt; to process &lt;a href="https://en.wikipedia.org/wiki/Digital_image" rel="noopener noreferrer"&gt;digital images&lt;/a&gt; through an &lt;a href="https://en.wikipedia.org/wiki/Algorithm" rel="noopener noreferrer"&gt;algorithm&lt;/a&gt;.&lt;/em&gt; &lt;br&gt;
~ Definition right off the page from Wikipedia &lt;/p&gt;

&lt;p&gt;Let's begin by simplifying the understanding of &lt;strong&gt;Image Processing&lt;/strong&gt; and moving on further with Image algorithms and different processes followed by implementing them using the &lt;strong&gt;PIL&lt;/strong&gt; library (quite a popular package of Python!). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0fp3kweid3a1xjx2yvoi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0fp3kweid3a1xjx2yvoi.gif" alt="excited"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;GIF Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Image processing&lt;/strong&gt; is just a simple way to look at a digital image, be it grey scaled or colored or any different mode and performing various operations/processes like image scaling/resizing, rotation, cropping and adjusting contrast, and many such familiar operations/processes.&lt;/p&gt;

&lt;h1&gt;
  
  
  🏃‍♀️ Table of Contents 🏃‍♂️
&lt;/h1&gt;

&lt;p&gt;Providing the entire content table so you're free to choose which topic you want to read! Enjoy reading. 😁&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Prerequistes&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;About the PIL&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Image Respresentation &amp;amp; its modes&lt;/em&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;PIL Implementation&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;em&gt;Image Processing Principles&lt;/em&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Nearest Neighbor&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Bilinear Interpolation&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Bicubic Interpolation&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Convolution Method&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;em&gt;Transformation with PIL&lt;/em&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Resizing Image&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Rotating Image&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  Before starting anything, do this!
&lt;/h2&gt;

&lt;p&gt;In this tutorial to perform different image processing on various images, we're using the PIL python library. Now certainly PIL is not just pre-installed on your machine. Thus we got to install &lt;strong&gt;python&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://pypi.org/project/pip/" rel="noopener noreferrer"&gt;pip&lt;/a&gt;&lt;/strong&gt; and last and the most important, &lt;strong&gt;PIL&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have &lt;a href=""&gt;anaconda&lt;/a&gt; installed on your machine, you don't have to do any of the steps mentioned below.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When you download &lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;python&lt;/a&gt;, PIP is installed along with it.  &lt;/p&gt;

&lt;p&gt;For installing PIL, we will install Pillow (Pillow is a maintained fork of PIL): &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;Pillow


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you want to code side by side along with this blog, I would suggest doing the following in your terminal: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;pil-image-processing &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;pil-image-processing
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;images


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We will be writing the programs within the &lt;code&gt;pil-image-processing&lt;/code&gt; directory. You can use any code editor however I will make use of &lt;code&gt;vim&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also, if you want to use the same images as I have in this blog, you can download the &lt;a href="https://github.com/devunf/pil-image-processing/blob/main/images/image.png" rel="noopener noreferrer"&gt;youtube icon&lt;/a&gt; and &lt;a href="https://github.com/devunf/pil-image-processing/blob/main/images/sunset.png" rel="noopener noreferrer"&gt;sunset picture&lt;/a&gt; and place them in your &lt;code&gt;images&lt;/code&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  PIL Library
&lt;/h2&gt;

&lt;p&gt;I will give a brief on what the PIL library is and what we'll cover with it.&lt;/p&gt;

&lt;p&gt;PIL library is quite a popular package provided by Python that handles all the image processing and functions that I mentioned earlier. It's in short called &lt;em&gt;Pillow&lt;/em&gt; also(I don't know why!). &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pillow is the “friendly” PIL fork by Alex Clark and Contributors.&lt;/em&gt; &lt;br&gt;
~ As mentioned in the &lt;a href="https://pypi.org/project/Pillow/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Image Representation &amp;amp; its modes
&lt;/h2&gt;

&lt;p&gt;Pixel is the smallest &amp;amp; the most important component of an image. A collection of pixels makes an image altogether. A pixel value always ranges from &lt;em&gt;0-255&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbdo2tzhjgw9pofythze0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbdo2tzhjgw9pofythze0.png" alt="pixel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An image always has a width (w) and height (h) and can be understood by its comparison through a matrix with w rows and h columns. &lt;/p&gt;

&lt;p&gt;We'll move on a step further to understand the different modes of images. Earlier I mentioned an image can be represented through a matrix. A matrix is 2-dimensional and this single matrix forms a single &lt;strong&gt;channel of the image&lt;/strong&gt;. That's a new term alert! &lt;/p&gt;

&lt;p&gt;When we fill the matrix in the single-channel with values ranging from &lt;em&gt;0-255&lt;/em&gt;, it will form a &lt;strong&gt;greyscale image&lt;/strong&gt;. Great so now we reached a level where we created a greyscale image. Greyscale image size is simply represented with &lt;code&gt;width x height&lt;/code&gt; format.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7wfdxsmh8zmvrvho2muh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7wfdxsmh8zmvrvho2muh.png" alt="greyscale"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's move on to form the colored digital images observed these days.&lt;/p&gt;

&lt;p&gt;For understanding the colored images, we'll go to legos. In legos, we build a tower by placing one lego over another. In this manner, each lego is like a single-channel. In RGB/colored images, we've 3 channels that are placed on top of each other to create a single image. &lt;/p&gt;

&lt;p&gt;In RGB, we have got the Red, Green, and Blue channels. Each of these channels is filled with values ranging from 0-255. Together, when these channels are together placed, we get a colored image. It's as simple as that theoretically. In practice, we know that an image has a width (w) represented as rows and height (h) represented as columns but in an RGB image, we also need to mention the channels (c). &lt;/p&gt;

&lt;p&gt;The RGB image size is represented as &lt;code&gt;width x height x channels&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F819su7ssi3af8io2nvnv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F819su7ssi3af8io2nvnv.png" alt="RGB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are various other modes apart from RGB &amp;amp; greyscale such as CYMK and RGBA (and so many others). &lt;/p&gt;

&lt;h4&gt;
  
  
  RGBA =&amp;gt; RGB + Alpha lchannel (handles opacity of the image)
&lt;/h4&gt;

&lt;h3&gt;
  
  
  PIL Implementation for different modes
&lt;/h3&gt;

&lt;p&gt;In PIL, there are several shortcodes for &lt;a href="https://pillow.readthedocs.io/en/latest/handbook/concepts.html#modes" rel="noopener noreferrer"&gt;modes&lt;/a&gt; in their documentation with which we will refer and perform simple operations. &lt;/p&gt;

&lt;h4&gt;
  
  
  1. Convert any image format to greyscale format
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/image.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;LA&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/greyscale.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, this just converted our colored image to greyscale, damn! I will explain what this code does: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import the &lt;code&gt;Image&lt;/code&gt; package from the PIL library to use the in-built functions.&lt;/li&gt;
&lt;li&gt;We open the image apply the &lt;strong&gt;LA&lt;/strong&gt; mode to convert to greyscale and assign it to the variable &lt;code&gt;img&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We save this new image by specifying the path.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;LA is not Los Angeles guys but a mode specified by PIL in their documentation. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

L -  (8-bit pixels, black, and white)
LA (L with alpha)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxs3re41fhv72vx07x83c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxs3re41fhv72vx07x83c.png" alt="result-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture taken from Google, updated by myself&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  2. Splitting colored image to their respective channel
&lt;/h4&gt;

&lt;p&gt;Here, a colored image has 3 layers as mentioned before: Red, Green &amp;amp; Blue. What we'll do is extract each channel separately from the image and save those individual channels. Simple!!&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getdata&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F28gruvj96s1se2wbn7kt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F28gruvj96s1se2wbn7kt.png" alt="original"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, we open the image and assign it to variable img. After that, we're extracting the data of a colored image. We also mentioned before that a channel of an image is formed through a matrix that encompasses the pixel values ranging from 0-255. &lt;/p&gt;

&lt;p&gt;Now for one channel, we've one matrix filled with pixel values. But in a colored image, we've 3 channels (red, green &amp;amp; blue) so we've three matrixes filled with a pixel value. &lt;/p&gt;

&lt;p&gt;Again, a matrix is represented in a 2-D array with rows and columns. Now we've to include the values of 3 matrixes so we do it using a 3-D array and it comes in this format. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[[
  [r(0,0), g(0,0), b(0,0)], [r(0,1), g(0,1), b(0,1)]], 
  [[r(1,0), g(1,0), b(1,0)], [r(1,1), g(1,1), b(1,1)]
]] 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This format is better understood diagrammatically as shown:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxprae0j4h2tcs3jg5409.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxprae0j4h2tcs3jg5409.png" alt="diagram-format"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus, the data we extract from the image will be of the format: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[[[202 112 104]
 [202 112 104]
 [202 112 104]
 ...
 [200 111 105]
 [200 111 105]
 [199 110 104]]

 [[202 112 104]
 [202 112 104]
 [202 112 104]
 ...
 [200 111 103]
 [200 111 103]
 [199 110 102]]]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's use this data and split this data so we can get the r pixel values for the red channel, g pixel values for the green channel, and b pixel values for the blue channel.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;red&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;pixel&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;green&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;blue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As we have seen the data is of 3-D array format, thus let's focus on extracting only the red matrix for now. In the 3-D array, the internal array is of the format &lt;code&gt;[r, g, b]&lt;/code&gt; and we need to take the first value of this array to get the red pixel values. We do this similarly for creating the green matrix and blue matrix.&lt;/p&gt;

&lt;p&gt;Let's use these 3 matrixes and save them. We can then see the separate red, green, and blue channels of the original image.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putdata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;red&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/red_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putdata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/blue_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putdata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;green&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/green_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here, we use the &lt;code&gt;putdata()&lt;/code&gt; in-built function to copy the matrix content into the original image and then saving it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxbfz5b3s9nhuwjgv2zsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxbfz5b3s9nhuwjgv2zsa.png" alt="result-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Image Processing - Behind The Scene Principles
&lt;/h2&gt;

&lt;p&gt;For image processing techniques such as rescaling/resizing and rotation are formed based on principals of - nearest neighbor, bilinear transformation &amp;amp; other principles I will explain in detail.&lt;/p&gt;

&lt;p&gt;Let's start with the simplest principle and climb up with more complex ones. Just note that all these principles I will be explaining theoretically in the simplest form and not mathematically. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Nearest Neighbor Principle
&lt;/h3&gt;

&lt;p&gt;In this principle, we have an original image(A) and we apply an image processing technique to convert it to a modified image(B).&lt;/p&gt;

&lt;p&gt;I will explain this by resizing an image from A (3x3) to B (9x9). The first step to do is take the coordinates of the A image, multiple it by 3, then we will get a coordinate in the B image. This new coordinate of image B will have the same pixel value as the original coordinate in image A had.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

A(0, 0) =&amp;gt; 110
A(0, 1) =&amp;gt; 120  
&amp;gt;&amp;gt;&amp;gt; x3 &amp;lt;&amp;lt;&amp;lt;
B(0, 0) =&amp;gt; 110
B(0, 3) =&amp;gt; 120 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, we need to find the pixel value B(0, 1), and to do that we do as followed: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

B(0, 1) =&amp;gt; ? 
&amp;gt;&amp;gt;&amp;gt; /3 &amp;lt;&amp;lt;&amp;lt; 
A(0, 1/3) =&amp;gt; no such coordinate exists, right?


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You're right no such coordinate exists but the nearest neighbor asks that is &lt;strong&gt;A(0, 1/3)&lt;/strong&gt; closer to &lt;strong&gt;A(0, 0)&lt;/strong&gt; or &lt;strong&gt;A(0, 1)&lt;/strong&gt;. Here, it is closer to &lt;strong&gt;A(0, 1)&lt;/strong&gt; thus the pixel value of &lt;strong&gt;B(0, 1)&lt;/strong&gt; will be the same as &lt;strong&gt;A(0, 0)&lt;/strong&gt;. Similarly, other coordinates are calculated as well! This is not so efficient, certainly!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Bilinear Interpolation
&lt;/h3&gt;

&lt;p&gt;As you would have understood if we use the nearest neighbor principle to resize or rotate an image, it won't produce an accurate output and will be pixelated. Thus, we use another principle - Bilinear Transformation.&lt;/p&gt;

&lt;p&gt;Let's take the sample example of resizing an image A(3x3) to image B(9x9). &lt;/p&gt;

&lt;p&gt;Before we understand bilinear transformation, we need to understand linear transformation. We'll take the same example as we did in the nearest neighbor. So we need to find &lt;strong&gt;B(0, 1)&lt;/strong&gt; and the way we do it is found &lt;strong&gt;A(0, 1/3)&lt;/strong&gt; and the manner we do it is: &lt;/p&gt;

&lt;p&gt;We have the pixel value &lt;strong&gt;A(0, 0)&lt;/strong&gt; and &lt;strong&gt;A(0, 1)&lt;/strong&gt; so first we find &lt;code&gt;1/3 * value @ A(0, 1)&lt;/code&gt; and &lt;code&gt;2/3 * value @ A(0, 0)&lt;/code&gt;. Add those up and round it, you got the pixel value for &lt;strong&gt;A(0, 1/3)&lt;/strong&gt; and that's your value for &lt;strong&gt;B(0, 1)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We use this method to find any coordinate between 2 given coordinates. In bilinear, we make use of 4 consecutive coordinates in the original image A. With these coordinates, we calculate an ideal coordinate in image A and scale it to a coordinate in image B. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foxl53kljkvx7xqyub33o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foxl53kljkvx7xqyub33o.png" alt="bilinear"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We have pixel values of &lt;strong&gt;A(0, 0)&lt;/strong&gt;, &lt;strong&gt;A(0, 1)&lt;/strong&gt;,  &lt;strong&gt;A(1, 0)&lt;/strong&gt;, and &lt;strong&gt;A(1, 1)&lt;/strong&gt;. First, we find the coordinates of the square blocks between the 2 coordinates of image A using the linear interpolation method.&lt;/li&gt;
&lt;li&gt;With the coordinates of the 2 square blocks, we can interpolate and find the coordinate of the triangle block(the chosen one!). &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once we find the coordinate of the triangle block, we just map it to image B.&lt;/p&gt;

&lt;p&gt;So that's the basic idea of how bilinear works. In this manner, we can find any coordinate between 2 coordinates in our image B. With this principle, we can get much accurate pixel values and a smoother modified image. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Bicubic Interpolation
&lt;/h2&gt;

&lt;p&gt;In bicubic interpolation, we make use of a cubic equation. However, as I have mentioned before we'll focus on the theoretical rather than the mathematical understanding of the principle. &lt;/p&gt;

&lt;p&gt;Let's look back at linear/bilinear interpolation to transform from image A to image B.&lt;/p&gt;

&lt;p&gt;The below diagram in the 2-D plane shows that b/w any 2 given coordinate is just a line and you can find any coordinate between those 2 using the linear interpolation method:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4i0rdd4nvrquwnpepu7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4i0rdd4nvrquwnpepu7d.png" alt="deep-explanation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this linear interpolation doesn't always provide a highly accurate or smooth result. Thus, we make use of bicubic. &lt;/p&gt;

&lt;p&gt;From this diagram, if I use the bicubic method, what it implies is if there are 2 given coordinates and there is the line joining those 2, then we will use the tangent/derivative at those 2 coordinates and make the curve and find any coordinate between those 2.&lt;/p&gt;

&lt;h3&gt;
  
  
  How are we calculating the derivatives at the coordinates?
&lt;/h3&gt;

&lt;p&gt;For calculating the tangent at those 2 given coordinates, we need the neighboring coordinates of those 2 as well! So easy, right? &lt;/p&gt;

&lt;p&gt;We use the linear interpolation method to calculate the ideal coordinate in bilinear interpolation using 4 coordinates.&lt;/p&gt;

&lt;p&gt;If we want to find the ideal coordinate between those 4 using bicubic, we'll need to use the extension as shown in the diagram. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp0k1s1rx6e4oamfgss13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp0k1s1rx6e4oamfgss13.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For bicubic, we'll do as followed: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For each row, we will find the coordinate (square blocks) between 2 given coordinates and we need to find the tangent at those 2 given coordinates using the neighbor of the given 2.&lt;/li&gt;
&lt;li&gt;Once the coordinates of the square blocks are calculated, we use the same method in 1 and get the ideal coordinate of the triangle block.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The coordinate of the triangle block is scaled to the coordinate in image B. This gives a much smoother transformation as compared to bicubic interpolation. &lt;/p&gt;

&lt;p&gt;Let's cover our last principle before we jump to implementation using PIL. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Convolution method
&lt;/h2&gt;

&lt;p&gt;This is an &lt;strong&gt;important&lt;/strong&gt; principle! It's important 'cause today principles like bi-cubic, bilinear is based upon the convolution principle itself.&lt;/p&gt;

&lt;p&gt;Let's begin by understanding convolution. In convolution let's say we have an image I(7x7) and what we'll do here is slide a kernel window K(3x3) over the image I such that we'll get a new image J(5x5) = I(7x7) * K(3x3)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F90ik1m65ww0no1qzi2gx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F90ik1m65ww0no1qzi2gx.png" alt="convolution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the diagram, we see that the kernel K slides over image I. &lt;br&gt;
Then when the kernel K is over a section of image I, it multiplies the pixel values of K and I and then adds them all up in the section, and we get a convoluted image pixel value. I know this sounds confusing so we'll understand this with an example. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffbefcneze73ehhw9q208.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffbefcneze73ehhw9q208.png" alt="convolution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that image, we have a section of image I and we've our kernel K. From the diagram, it's understandable how the 9-pixel values result in a 1 convoluted pixel value. In this manner, we continue to slide the kernel K over the entire image I and get a convoluted image J (I * K). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is a heavy process, don't let anyone tell you different!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before moving further, I would like to clarify that these methods that I specified are used as filters to perform the transformation in images.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing transformation with a simple PIL
&lt;/h2&gt;

&lt;p&gt;According to the documentation of PIL: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image resizing methods &lt;code&gt;resize()&lt;/code&gt; and &lt;code&gt;thumbnail()&lt;/code&gt; take a resample argument, which tells which filter should be used for resampling. Possible values are &lt;code&gt;PIL.Image.NEAREST&lt;/code&gt;, &lt;code&gt;PIL.Image.BILINEAR&lt;/code&gt;, &lt;code&gt;PIL.Image.BICUBIC&lt;/code&gt; and &lt;code&gt;PIL.Image.ANTIALIAS&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;~&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The upscaling performance of the LANCZOS filter has remained the same. For the BILINEAR filter, it has improved by 1.5 times and for BICUBIC by four times.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;From those 2 contexts from documentation, we know what Nearest, Bilinear, and Bicubic are, so that's cool! Now, what's Antialias and Lanczos? &lt;br&gt;
Antialias is a high-quality filter based on convolutions (we learned this!). Now Antilias filter is just an alias of Lanczos. So Lanczos and antialias are based on convolution.&lt;/p&gt;

&lt;p&gt;Let's implement resizing using these filters with PIL. &lt;/p&gt;

&lt;p&gt;In the documentation, for using the filters while resizing and rotation we can use their names explicitly or the number assigned for them.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

NEAREST = NONE = 0
BILINEAR = LINEAR = 2
BICUBIC = CUBIC = 3
LANCZOS = ANTIALIAS = 1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  1. Resizing an image using different filters
&lt;/h3&gt;

&lt;p&gt;We're going to re-use the &lt;a href="https://github.com/devunf/pil-image-processing/blob/main/images/sunset.png" rel="noopener noreferrer"&gt;sunset&lt;/a&gt; image that we did while splitting the image into different channels. Let's get coding!&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;550&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;nearest_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;lanczos_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bilinear_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bicubic_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;nearest_resize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/nearest_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;lanczos_resize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/lanczos_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bilinear_resize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/bilinear_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bicubic_resize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/bicubic_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here, we're resizing the original image using different filters. With the current image, you may not be able to see much difference as shown. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwn4n1bi26pvyj5ug9mby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwn4n1bi26pvyj5ug9mby.png" alt="result-resize"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy4g5e60dopfcdzvse28j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy4g5e60dopfcdzvse28j.png" alt="result-resize-observable"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this particular image provides a good difference between resizing between different filters. I would suggest looking at the filters that have been used by us in this blog and observe the difference.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Rotating an image using different filters
&lt;/h3&gt;

&lt;p&gt;We'll be using the filters to rotate an image by any degree we wish to. However, there is a problem when rotation happens to let's say 30 or 45 degrees, the edges get clipped off. If we don't want that we'll be setting &lt;code&gt;expand=true&lt;/code&gt; which will prevent that! &lt;/p&gt;

&lt;p&gt;In resizing, we used numbers to depict what kind of filter we want to use over the image while resizing. Here, we'll explicitly type their names out and again use the same &lt;a href="https://github.com/devunf/pil-image-processing/blob/main/images/sunset.png" rel="noopener noreferrer"&gt;sunset&lt;/a&gt; image. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;nearest_rotate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NEAREST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bilinear_rotate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BILINEAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bicubic_rotate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BICUBIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;nearest_rotate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/nearest_rotate_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bilinear_rotate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/bilinear_rotate_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bicubic_rotate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/bicubic_rotate_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Here, the &lt;strong&gt;Lanczos&lt;/strong&gt; filter can't be used for rotation as it is not implemented by PIL itself and quite a heavy process so doesn't hold any advantage over &lt;strong&gt;bicubic&lt;/strong&gt; for now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;PIL is not limited to just resizing, rotation, splitting images but it can do so much more. Everything you perform on photo editing tools such as crop, copy-pasting, merging 2 images can be achieved through PIL just through few lines of code. In this, I have only used the &lt;code&gt;Image&lt;/code&gt; module but there are many modules for PIL itself.&lt;/p&gt;

&lt;p&gt;For any additional resources for PIL, just look through their &lt;a href="https://pillow.readthedocs.io/en/stable/reference/index.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, and certainly if stuck, stack overflow always provides every answer. PIL is an effective library and I have covered the 2 most commonly used operations and the principles that reside behind the transformation.&lt;/p&gt;

&lt;p&gt;The sources for each code is present on &lt;a href="https://github.com/devunf/pil-image-processing" rel="noopener noreferrer"&gt;Github&lt;/a&gt; as well, so you can refer from there and code side by side too! &lt;/p&gt;

&lt;p&gt;If any questions arise regarding PIL or anything mentioned in the article, feel free to mention it in the comments! Till then, goodbye. 👋 &lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🐋 ELI5 Docker: Easy Docker Concepts in 5 Minutes!</title>
      <dc:creator>Sahil Bondre</dc:creator>
      <pubDate>Sun, 17 Jan 2021 14:13:40 +0000</pubDate>
      <link>https://dev.to/devunf/eli5-docker-easy-docker-concepts-in-5-minutes-3812</link>
      <guid>https://dev.to/devunf/eli5-docker-easy-docker-concepts-in-5-minutes-3812</guid>
      <description>&lt;h1&gt;
  
  
  A Story
&lt;/h1&gt;

&lt;p&gt;Let's start with a story first. Mary was a painter in the Medieval era who was really good at drawing portraits. She wanted some career change. Nature was more exciting to her than the faces of people. So she decided to travel. She travelled all the way to the beautiful Fjords in Norway for some inspiration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu7q52ia106w8gz5w6cj5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu7q52ia106w8gz5w6cj5.jpg" alt="Fjords" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@robertbye?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Robert Bye&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/fjords?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;She quickly realized that the environment around her was not suitable. &lt;br&gt;
It was way too cold. Norwegian food wasn't her favourite either. And she couldn't work without her canvas and pigments.&lt;/p&gt;

&lt;p&gt;She came up with a plan. On a piece of paper, she noted all the things she needed to live, eat, sleep, and paint in the foreign land. She further listed where to get them and wrote the steps to build a small abode to live and work for a few weeks peacefully.&lt;/p&gt;

&lt;p&gt;She went to Amazon (the internet was built in Renaissance!), fetched all the things and made her a small cabin according to her paper's recipe. She then could work peacefully in an environment that was suitable to her. A few days later, a friend who fancied changing jobs wanted to join her too. Mary then gave the page containing the instructions to John. Since all the ingredients and steps were already documented, John made his own cabin in no time and got to work in Norway too. End of story!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F382bghpw20g8hkazqceu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F382bghpw20g8hkazqceu.jpg" alt="Cabin in Woods" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@olivier_twwli?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Olivier Guillard&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/cabin?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  What's Docker
&lt;/h1&gt;

&lt;p&gt;Let's get back to Docker now:&lt;/p&gt;

&lt;p&gt;The painters in the story are like the programs that we write. They might work correctly on our machine but maybe not on someone else's computer. The other system may have a different version of Python or Node, different pre-installed packages or even a completely different OS. As in the story, our applications won't work in a completely different environment, so we need to build a small cabin to do their job comfortably. These are known as &lt;strong&gt;Images&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Images
&lt;/h3&gt;

&lt;p&gt;Docker Images include our application's source code and all the tools, libraries, and packages that it needs to run. We can run these Images as an instance of a &lt;strong&gt;Container&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Container
&lt;/h3&gt;

&lt;p&gt;A Container is a lightweight, independent, executable software package with everything you need to run the application. Images are more of a blueprint, and Containers are more like an executable file.&lt;br&gt;
Remember the page that Mary had made? In the Docker world, we call it the &lt;strong&gt;Dockerfile&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Dockerfile&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A Dockerfile is a text file that includes the recipe to build the Docker Image. It specifies the OS, languages, environmental variables, file locations, network ports, and other components that our app requires.&lt;/p&gt;

&lt;p&gt;Mary could build everything she needed with the help of Renaissance Amazon. Now that's like Docker. To quote the official documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Docker Registry
&lt;/h3&gt;

&lt;p&gt;Now let's assume she posted a picture of her page with the recipe (along with links to Amazon) on her Medieval Blog so other people can use it, that would be an example of a public Docker Registry. &lt;br&gt;
A Docker Registry is where the Docker Images are stored. The registry can be either private or public. Several people can collaborate and share images by uploading them to the registry.&lt;br&gt;
One such example of a Docker registry is the Docker Hub. What Github is for code, Docker Hub is for Docker Images.&lt;/p&gt;

&lt;h1&gt;
  
  
  Next Steps
&lt;/h1&gt;

&lt;p&gt;So, I've covered all the basic concepts that you'll require to get started to use Docker. There are several resources on the internet from where you can learn docker. I'll list down a few that I've used personally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/get-started/" rel="noopener noreferrer"&gt;Docker's Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/veggiemonk/awesome-docker" rel="noopener noreferrer"&gt;Awesome Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=fqMOX6JJhGo" rel="noopener noreferrer"&gt;Docker Tutorial for Beginners (2 hour video)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=gAkwW2tuIqE" rel="noopener noreferrer"&gt;Learn Docker in 7 Easy Steps (11 minute video)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=aLipr7tTuA4" rel="noopener noreferrer"&gt;MicroNugget: What is Docker and How Does it Work? (10 minute video)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installing Docker
&lt;/h3&gt;

&lt;p&gt;The Docker suite contains two principal tools: Docker Engine and Docker Desktop. &lt;br&gt;
The &lt;a href="https://docs.docker.com/engine/" rel="noopener noreferrer"&gt;Docker Engine&lt;/a&gt; is the core set of docker tools required to run docker commands and containers on your machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/desktop/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; is a GUI that talks to the underlying Docker Engine to make your life easy.&lt;/p&gt;

&lt;h1&gt;
  
  
  What's next?
&lt;/h1&gt;

&lt;p&gt;Docker is among the first steps to learn about Microservices and DevOps. You can start learning about the microservice vs monolith philosophy, container orchestration, Kubernetes there's lots and lots of great stuff to learn!&lt;/p&gt;




&lt;p&gt;🌟 Thank's for reading! I'd love to hear any feedback, opinions, and ideas for what I should write on next.&lt;br&gt;
😄 Have a wonderful day!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>beginners</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
