{"id":3513,"date":"2026-10-21T20:29:11","date_gmt":"2026-10-21T12:29:11","guid":{"rendered":"http:\/\/www.trader-john.com\/blog\/?p=3513"},"modified":"2026-10-21T20:29:11","modified_gmt":"2026-10-21T12:29:11","slug":"how-to-extract-a-specific-color-from-an-image-using-pillow-49d9-73e7cb","status":"publish","type":"post","link":"http:\/\/www.trader-john.com\/blog\/2026\/10\/21\/how-to-extract-a-specific-color-from-an-image-using-pillow-49d9-73e7cb\/","title":{"rendered":"How to extract a specific color from an image using Pillow?"},"content":{"rendered":"<p>If you\u2019ve ever worked with image processing, you\u2019ve probably found yourself in a spot where you need to isolate a single color\u2014say, the bright red of a product logo from a product shot, or the soft blue of a brand accent element from a marketing graphic. For Python users, Pillow is the go-to library for this kind of work, and as a long-time supplier of Pillow packages to developers and small-scale dev teams, I\u2019ve fielded dozens of questions about how to pull off this specific color extraction without wasting hours fumbling with complex tools. This isn\u2019t magic, just straightforward, repeatable steps that work for most common image types, and I\u2019m breaking it down here the same way I walk new clients through it when they order Pillow from me. <a href=\"https:\/\/www.tangjin-hometex.com\/pillow\/\">Pillow<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.tangjin-hometex.com\/uploads\/202227045\/small\/urban-cotton-comforter-set25001689193.jpg\"><\/p>\n<p>First, let\u2019s clear up a quick point: when we talk about extracting a specific color from an image, we\u2019re not just picking a random pixel\u2019s hex code\u2014we\u2019re targeting all pixels that fall within a narrow range of that color\u2019s hue, saturation, and brightness values, accounting for minor lighting shifts, compression artifacts, or edge blur. Pillow makes this accessible because it handles both RGB (the standard for most digital images) and HSV (Hue, Saturation, Value, a color model that\u2019s way easier to work with when you want to target a specific color range) natively, no extra plugins required. That\u2019s part of why my customers keep coming back for Pillow\u2014its core functionality is built for exactly these sorts of real-world tasks, not just niche enterprise use cases.<\/p>\n<p>Let\u2019s start with the basics you\u2019ll need to set up, if you haven\u2019t already. First, install Pillow via pip. You\u2019d be surprised how many people skip this step and waste time with broken, outdated packages\u2014something I hear about all the time. For most users, a simple <code>pip install pillow<\/code> works, but if you\u2019re working with large, high-resolution images, I recommend grabbing the precompiled binary wheels I stock for Pillow, since they cut down on installation time and avoid common compilation errors on Windows and macOS. Once you have Pillow installed, the first step in any color extraction workflow is loading your image correctly. Open it with <code>Image.open()<\/code>\u2014easy, but pro tip: always convert your image to RGB mode right after loading, even if it\u2019s a PNG or JPG that looks like it\u2019s already in color. Some image formats (like grayscale or CMYK, common for print work) will throw off your color values, so converting to standard RGB ensures consistency.<\/p>\n<p>Next, the critical part: converting your image to HSV. This is where most people stumble, because if you stick with RGB, you\u2019ll be trying to filter red pixels that are slightly darker or brighter than your target, and you\u2019ll accidentally cut out too much or keep too much. HSV breaks colors into three separate, intuitive parts: Hue (the actual color on a 0\u2013360 degree wheel, where red is 0\u00b0, green is 120\u00b0, blue is 240\u00b0), Saturation (how \u201cvivid\u201d the color is, from 0 for gray to 255 for pure color), and Value (brightness, from 0 for black to 255 for pure white). To convert an RGB image to HSV in Pillow, you\u2019ll use the <code>convert('HSV')<\/code> method on your Image object. This gives you a three-channel HSV array, which is perfect for defining your target color range.<\/p>\n<p>Let\u2019s use a concrete example to make this tangible. Suppose you have a product image with a bright brand red, and you want to extract all red elements from it. First, pick your target hue value: pure red is 0 in HSV, but most real-world reds will be between 0 and 10 degrees, to account for slight lighting shifts. Next, set a saturation range: if you only want vivid, true red (not washed-out pinks or faded tones), you might set the lower saturation to 150, so any pixel that\u2019s too gray (saturation below 150) gets excluded. Then for brightness, set a range from 50 (so you don\u2019t pick up dark black edges) up to 255 (so you get the brightest red highlights). This gives you a lower bound of <code>(0, 150, 50)<\/code> and an upper bound of <code>(10, 255, 255)<\/code> for your red range. These numbers aren\u2019t set in stone\u2014adjust based on your image\u2019s lighting and how precise you need the extraction to be.<\/p>\n<p>Now, to turn that range into a mask, Pillow\u2019s <code>ImageOps<\/code> and <code>numpy<\/code> (we use numpy alongside Pillow for this step in almost all our enterprise supply orders, since it\u2019s lightweight and plays perfectly with Pillow\u2019s image arrays) make this simple. First, convert your HSV image to a numpy array, so you can do element-wise comparisons. Then, create a mask array where each pixel is <code>True<\/code> if it falls within your HSV range, and <code>False<\/code> if it doesn\u2019t. If you\u2019re not familiar with numpy, don\u2019t overcomplicate it\u2014this is just a way to check every pixel against your target values in one line, instead of looping through each pixel manually. Once you have your mask, you can use it to isolate your color: either apply it to the original image to keep only the target color, or invert it to keep everything else.<\/p>\n<p>Wait, let\u2019s talk about a common pitfall here: some users try to use RGB ranges instead of HSV, and they end up with a lopsided extraction. For example, pure red in RGB is <code>(255, 0, 0)<\/code>, but a dark red might be <code>(150, 0, 0)<\/code> and a light red might be <code>(255, 100, 100)<\/code>. If you set an RGB range for red, you\u2019ll accidentally pick up pinks that are too light or browns that are too dark, because RGB mixes all color channels together. HSV solves this by separating color identity (hue) from its intensity and vividness, which makes it far more reliable for targeted color work. That\u2019s why I always advise new Pillow users to practice with HSV first\u2014once you get the hang of adjusting hue, saturation, and value ranges, it\u2019s way less trial and error than guessing at RGB values.<\/p>\n<p>Another step that often gets overlooked: handling anti-aliased edges. If your image has smooth, blurred edges around your target color (like a logo on a white background), the edge pixels won\u2019t be pure red\u2014they\u2019ll be semi-transparent or have a mix of your target color and the background. If you just use a hard mask, you\u2019ll end up with jagged, pixelated edges. To fix this, you can slightly expand your HSV range by a few degrees of hue, and then use a small blur on your mask, or use the <code>alpha_composite<\/code> method in Pillow to blend the mask edges smoothly. I include a short example of this in the documentation I send with every Pillow order, because it\u2019s a tiny tweak that makes extracted colors look professional, not like a bot did the work.<\/p>\n<p>Let\u2019s test this workflow with a real code snippet, the same one I walk customers through when they\u2019re setting up their first color extraction script. First, load your image, convert it to RGB, then to HSV:<\/p>\n<p>from PIL import Image<br \/>\nimport numpy as np<\/p>\n<h1>Load your image (I always recommend using image files from local storage, not URLs, for consistency)<\/h1>\n<p>img = Image.open(&quot;product_shot.jpg&quot;).convert(&quot;RGB&quot;)<\/p>\n<h1>Convert to HSV for color targeting<\/h1>\n<p>hsv_img = img.convert(&quot;HSV&quot;)<br \/>\nhsv_array = np.array(hsv_img)<\/p>\n<h1>Define your HSV range for bright red\u2014adjust these values to match your target color<\/h1>\n<p>lower_red = np.array([0, 150, 50])<br \/>\nupper_red = np.array([10, 255, 255])<\/p>\n<h1>Create the mask: True for pixels within your range, False otherwise<\/h1>\n<p>mask = np.all((hsv_array &gt;= lower_red) &amp; (hsv_array &lt;= upper_red), axis=2)<\/p>\n<h1>Convert the mask back to a Pillow Image, then use it to isolate the color<\/h1>\n<p>mask_img = Image.fromarray((mask * 255).astype(np.uint8))<br \/>\nextracted_color = Image.composite(img, Image.new(&quot;RGB&quot;, img.size, (255, 255, 255)), mask_img)<\/p>\n<h1>Save your result<\/h1>\n<p>extracted_color.save(&quot;red_extract.png&quot;)<\/p>\n<p>That\u2019s it\u2014no fancy tools, just Pillow and numpy, both of which I supply to dev teams for exactly this kind of project. Now, let\u2019s go over why this works, and where people usually mess it up. First, if your extraction is leaving out parts of the target color, your HSV range is too narrow\u2014widen the upper and lower hue bounds. If it\u2019s picking up too much extra color, shrink the saturation or value range. If your image is a PNG with transparency, just make sure to load it in RGBA mode first, convert that to HSV, and the mask will work the same way.<\/p>\n<p>I\u2019ve also noticed that a lot of developers confuse extracting a color with changing a color\u2019s saturation, which is a different task\u2014this workflow is specifically for isolating one color, not modifying it. That\u2019s a key distinction, and it\u2019s why I make sure to clarify it in all my Pillow supply communications. If someone is asking to change all red pixels to blue, that\u2019s a simple color replacement, but extracting means making those red pixels the only visible ones, or turning the rest of the image transparent.<\/p>\n<p>For more complex images, like photos with multiple colors or uneven lighting, you might need to use a second mask to account for shadows or highlights. For example, if your red logo has a darker shaded area at the bottom, you can add a range of lower brightness values to your HSV upper and lower bounds so that the shaded parts are included. This is where testing small adjustments to your HSV values comes in\u2014spend 10 minutes tweaking the range on a small test image, and you\u2019ll save hours of reworking a final product.<\/p>\n<p>Now, as a supplier of Pillow, I can\u2019t stress enough how reliable this library is for this kind of work. A lot of open-source image libraries have buggy color conversion or poor performance with large images, but Pillow is maintained consistently, and its color mode handling is accurate across all common image formats. I\u2019ve supplied Pillow to teams that use color extraction for e-commerce product catalogs, graphic design, and even medical imaging\u2014this workflow is flexible enough for all those use cases.<\/p>\n<p>If you\u2019re just getting started, I recommend testing this with a sample image that has a clear, single target color first, before moving to more complex shots. Play with different hue ranges: if you\u2019re extracting blue, your hue range will be around 220 to 240, and green is around 100 to 140. Saturation and value ranges will stay similar, but the hue is the key number that changes based on your target color.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.tangjin-hometex.com\/uploads\/202327045\/small\/gravity-blanket4f4981df-dc7e-4bc0-8b3f-52a762b1f0fb.jpg\"><\/p>\n<p>At the end of the day, extracting a specific color from an image with Pillow isn\u2019t about mastering complicated algorithms\u2014it\u2019s about understanding how HSV color space works, and using Pillow\u2019s built-in functions to turn that understanding into a usable mask. If you\u2019re working on a project that requires this kind of image processing, or you need a reliable supply of Pillow packages to streamline your workflow, feel free to reach out to discuss your specific needs. We can help you get set up with the right version of Pillow, troubleshoot any color conversion issues, or even adapt this workflow to fit your exact image processing tasks.<\/p>\n<p><a href=\"https:\/\/www.tangjin-hometex.com\/quilt\/cotton-quilt\/\">Cotton Quilt<\/a> REFERENCES<br \/>\nPillow Documentation: Image.convert() Method<br \/>\nPillow Documentation: Image.composite() Method<br \/>\nOpenCV Documentation: HSV Color Space Basics (for context, though we use Pillow here)<br \/>\nPython Software Foundation: NumPy Array Manipulation Guide<\/p>\n<hr>\n<p><a href=\"https:\/\/www.tangjin-hometex.com\/\">Hangzhou Tangjin Textile Co., Ltd.<\/a><br \/>Hangzhou Tangjin Textile Co., Ltd. is one of the most professional pillow manufacturers and suppliers in China, featured by quality products and good service. Please rest assured to wholesale custom made pillow at competitive price from our factory.<br \/>Address: No.55, Louying Road, Louta Town, Xiaoshan District, Hangzhou City, Zhejiang Province<br \/>E-mail: wendy@tangjintex.com<br \/>WebSite: <a href=\"https:\/\/www.tangjin-hometex.com\/\">https:\/\/www.tangjin-hometex.com\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019ve ever worked with image processing, you\u2019ve probably found yourself in a spot where you &hellip; <a title=\"How to extract a specific color from an image using Pillow?\" class=\"hm-read-more\" href=\"http:\/\/www.trader-john.com\/blog\/2026\/10\/21\/how-to-extract-a-specific-color-from-an-image-using-pillow-49d9-73e7cb\/\"><span class=\"screen-reader-text\">How to extract a specific color from an image using Pillow?<\/span>Read more<\/a><\/p>\n","protected":false},"author":54,"featured_media":3513,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[3476],"class_list":["post-3513","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-industry","tag-pillow-42ff-742ddd"],"_links":{"self":[{"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/posts\/3513","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/users\/54"}],"replies":[{"embeddable":true,"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/comments?post=3513"}],"version-history":[{"count":0,"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/posts\/3513\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/posts\/3513"}],"wp:attachment":[{"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/media?parent=3513"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/categories?post=3513"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.trader-john.com\/blog\/wp-json\/wp\/v2\/tags?post=3513"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}