{"id":46825,"date":"2025-02-14T00:00:00","date_gmt":"2025-02-14T08:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/color-palettes-extraction-using-webcam-and-ai\/"},"modified":"2025-11-13T12:57:14","modified_gmt":"2025-11-13T20:57:14","slug":"color-palettes-extraction-using-webcam-and-ai","status":"publish","type":"post","link":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/","title":{"rendered":"Color Palettes Extraction Using Webcam and AI"},"content":{"rendered":"<p>In this tutorial, we will explore how to extract color palettes from images captured via a webcam using Node.js, GridDB, and OpenAI. By leveraging Node.js for server-side scripting, GridDB for efficient data storage, and OpenAI for advanced image processing, we will create a seamless pipeline to capture images, analyze them, and generate dynamic color palettes. This guide will walk you through setting up your environment, capturing images from your webcam, and using AI to extract and store color data effectively.<\/p>\n<h2>Prerequisites<\/h2>\n<p>Before we dive in, ensure the following software is installed on your machine:<\/p>\n<ul>\n<li>Node.js<\/li>\n<li>GridDB<\/li>\n<li>OpenAI API access<\/li>\n<li>Browser with a webcam access<\/li>\n<\/ul>\n<h2>Running The Project<\/h2>\n<p>Clone the source code from this <a href=\"https:\/\/github.com\/griddbnet\/Blogs\/tree\/color-extraction\">GitHub repository<\/a>.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">git clone https:\/\/github.com\/griddbnet\/Blogs.git --branch color-extraction<\/code><\/pre>\n<\/div>\n<p>This project also needs to install Node.js and GridDB for this project to run. If the software requirements are installed, change the directory to the <code>apps<\/code> project directory and then install all the dependencies:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">cd color-detection-openai\ncd apps\nnpm install<\/code><\/pre>\n<\/div>\n<p>Create a <code>.env<\/code> file and copy all environment variables from the <code>.env.example<\/code> file. We need an OpenAI key for this project, please look in the &#8220;Getting Started&#8221; section to get started.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">OPENAI_API_KEY=sk-proj-secret\nVITE_APP_URL=http:\/\/localhost:3000<\/code><\/pre>\n<\/div>\n<p>You can change the <code>VITE_APP_URL<\/code> to your needs and then run the project by running this command:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">npm run start:build<\/code><\/pre>\n<\/div>\n<p>Go to the browser and enter the URL set on <code>VITE_APP_URL<\/code>, which in this case is <code>http:\/\/localhost:3000<\/code>. Make sure to enable the webcam in your browser, then click the <strong>Capture<\/strong> button to take a photo using the web camera.<\/p>\n<h2>Setting Up the Environment<\/h2>\n<h3>1. Installing Node.js<\/h3>\n<p>This project will run on the Node.js platform. You need to install it from <a href=\"https:\/\/nodejs.org\/en\/download\">here<\/a>. For this project, we will use the <code>nvm<\/code> package manager and Node.js v16.20.2 LTS version.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\"># installs nvm (Node Version Manager)\ncurl -o- https:\/\/raw.githubusercontent.com\/nvm-sh\/nvm\/v0.39.7\/install.sh | bash\n\n# download and install Node.js\nnvm install 16\n\n# verifies the right Node.js version is in the environment\nnode -v # should print `v16.20.2`\n\n# verifies the right NPM version is in the environment\nnpm -v # should print `8.19.4``<\/code><\/pre>\n<\/div>\n<p>To connect Node.js and GridDB database, we need the <a href=\"https:\/\/github.com\/nodejs\/node-addon-api\">gridb-node-api<\/a> npm package which is a Node.js binding developed using GridDB C Client and Node addon API.<\/p>\n<h3>2. Setting Up GridDB<\/h3>\n<p>We will use the GridDB database to save recipes and it&#8217;s nutrition analysis. Please look at the <a href=\"https:\/\/docs.griddb.net\/latest\/gettingstarted\/using-apt\/#install-with-apt-get\">guide<\/a> for detailed installation. We will use Ubuntu 20.04 LTS here.<\/p>\n<p>Run GridDB and check if the service is running. Use this command:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">sudo systemctl status gridstore<\/code><\/pre>\n<\/div>\n<p>If not running try to run the database with this command:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">sudo systemctl start gridstore<\/code><\/pre>\n<\/div>\n<h3>3. Get The OpenAI Key<\/h3>\n<p>To get the OpenAI key, create a project first and then <a href=\"https:\/\/platform.openai.com\/api-keys\">create a key<\/a>. The important thing is you should save the OpenAI key on the <code>.env<\/code> file and ensure not to include it in version control by adding it to the <code>.gitignore<\/code>.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">OPENAI_API_KEY=sk-proj-secret<\/code><\/pre>\n<\/div>\n<p>Another crucial factor is to select models that are accessible for the project. For this project, we will utilize <code>gpt-4o<\/code> models for image recognition and extracting colors from the image.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/limit-models.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/limit-models.png\" alt=\"\" width=\"2947\" height=\"1651\" class=\"aligncenter size-full wp-image-31371\" srcset=\"\/wp-content\/uploads\/2025\/02\/limit-models.png 2947w, \/wp-content\/uploads\/2025\/02\/limit-models-300x168.png 300w, \/wp-content\/uploads\/2025\/02\/limit-models-1024x574.png 1024w, \/wp-content\/uploads\/2025\/02\/limit-models-768x430.png 768w, \/wp-content\/uploads\/2025\/02\/limit-models-1536x861.png 1536w, \/wp-content\/uploads\/2025\/02\/limit-models-2048x1147.png 2048w, \/wp-content\/uploads\/2025\/02\/limit-models-150x85.png 150w, \/wp-content\/uploads\/2025\/02\/limit-models-600x336.png 600w\" sizes=\"(max-width: 2947px) 100vw, 2947px\" \/><\/a><\/p>\n<p>The AI model&#8217;s response is non-deterministic, which means sometimes the response is not exactly what we want. By default this project uses the <code>gpt-4o-mini<\/code> model, in case the response is not quite right, you can change it to a more powerful model, such as the <code>gpt-4o<\/code> model.<\/p>\n<h2>Capturing Images with MediaStream<\/h2>\n<p>To capture images, we can use <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Media_Capture_and_Streams_API\">MediaStream API<\/a>. It is an API related to WebRTC which provides support for streaming audio and video data. Before capturing an image from the web camera, we first need to initialize the web camera:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const initializeWebcam = () => {\n    navigator.mediaDevices.getUserMedia({\n            video: true\n        })\n        .then(stream => {\n            videoRef.current.srcObject = stream\n        })\n        .catch(error => {\n            console.error('getUserMedia error:', error)\n        })\n}<\/code><\/pre>\n<\/div>\n<p>And then to capture the image from the video, we can use the <code>drawImage()<\/code> function:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const captureImage = () => {\n    const context = canvasRef.current.getContext('2d')\n    context.drawImage(videoRef.current, 0, 0, canvasRef.current.width, canvasRef.current.height)\n\n    const base64Image = canvasRef.current.toDataURL('image\/jpeg')\n    processImage(base64Image)\n}<\/code><\/pre>\n<\/div>\n<p>The <code>drawImage()<\/code> function will capture the current frame from the video stream and render it onto the canvas. This allows for further image data manipulation, processing, or conversion. In the provided code, the drawn image on the canvas is converted to a base64-encoded string using the <code>toDataURL()<\/code> function, which is then sent to a server for processing.<\/p>\n<h2>Processing Images with OpenAI<\/h2>\n<p>The image processing on the server is quite simple. The web app will send a base64-encoded image to the <code>\/process-image<\/code> route.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">app.post('\/process-image', async (req, res) => {\n    const {\n        image\n    } = req.body\n\n    if (!image) {\n        return res.status(400).json({\n            error: 'No image provided'\n        })\n    }\n    \/\/ eslint-disable-next-line no-undef\n    const result = await getColorAnalysis(image)\n    res.json(result.choices[0])\n})<\/code><\/pre>\n<\/div>\n<p>Then to get the color analysis from the image, we will use the <code>gpt-4o-mini<\/code>  model from OpenAI. The <code>getColorAnalysis()<\/code> function will take the base64-encoded image and then process it.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">async function getColorAnalysis(base64Image) {\n    const response = await openai.chat.completions.create({\n        model: \"gpt-4o-mini-2024-07-18\",\n        messages: [{\n                role: \"system\",\n                content: systemPrompt\n            },\n            {\n                role: \"user\",\n                content: [{\n                        type: \"image_url\",\n                        image_url: {\n                            url: base64Image\n                        }\n                    },\n                    {\n                        type: \"text\",\n                        text: userPrompt\n                    }\n                ]\n            }\n        ],\n        temperature: 0.51,\n        max_tokens: 3000,\n        top_p: 1,\n        frequency_penalty: 0,\n        presence_penalty: 0,\n    });\n\n    return response;\n}<\/code><\/pre>\n<\/div>\n<p>OpenAI&#8217;s model response is determined by the prompt given. For a color analysis, use the specific prompt:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const userPrompt = \"Extract the seven most prominent colors from the provided image. Use color clustering techniques to identify and present these colors in Hex values. Answer with the raw array values ONLY. DO NOT FORMAT IT.\";<\/code><\/pre>\n<\/div>\n<p>We can get a better result by adding a system prompt to the OpenAI model. This system prompt behaves like a command for the OpenAI model to behave for a specific persona, which is <strong>a professional color analyst<\/strong>.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">const systemPrompt = `You are an AI specialized in colorimetry, the science and technology of color detection and measurement. You possess deep knowledge of the principles of color science, including color spaces, color matching functions, and the use of devices such as spectrophotometers and colorimeters. You provide accurate and detailed analyses of color properties, offer solutions for color consistency issues, and assist in applications ranging from imaging and printing to manufacturing and display technologies. Use your expertise to answer questions, solve problems, and provide color detection and measurement guidance.`;<\/code><\/pre>\n<\/div>\n<p>The prompt can also specify the model format response. In this project, we want the array of colors from the image colors analysis. The OpenAI model response should be in the form:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">['#2A2C9B', '#F08A7D', '#8E5DB2', '#E8A1A3', '#4D3B9E', '#7F3C8F', '#B57AB3']<\/code><\/pre>\n<\/div>\n<p>Where each item in the array is a color in the hex format.<\/p>\n<h2>Storing Data in GridDB<\/h2>\n<p>We utilize the GridDB database for data storage. Here are the main data fields along with their descriptions:<\/p>\n<table>\n<thead>\n<tr>\n<th>Column Name<\/th>\n<th>Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>id<\/td>\n<td>INTEGER<\/td>\n<td>Unique identifier for each row.<\/td>\n<\/tr>\n<tr>\n<td>picture<\/td>\n<td>BLOB<\/td>\n<td>Base64 image encoding.<\/td>\n<\/tr>\n<tr>\n<td>colors<\/td>\n<td>STRING<\/td>\n<td>List of colors in Hex format.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The <code>saveData()<\/code> function is a wrapper for the <code>insert()<\/code> function in the <code>libsgriddb.cjs<\/code> file. It is responsible for saving data into the database. Only two main fields are saved in the database.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">export async function saveData({ image, genColors }) {\n    const id = generateRandomID()\n    const picture = Buffer(image)\n    const colors = String(genColors)\n\n    const packetInfo = [parseInt(id), picture, colors]\n    const saveStatus = await GridDB.insert(packetInfo, collectionDb)\n    return saveStatus\n}<\/code><\/pre>\n<\/div>\n<p>The save data function will be executed on the server route <code>\/process-image<\/code> after the color analysis of the image. Every time a user captures an image, it will be automatically sent to the server and the resulting data will be saved to the database.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">app.post('\/process-image', async (req, res) => {\n    const { image } = req.body\n\n    if (!image) {\n        return res.status(400).json({ error: 'No image provided' })\n    }\n\n    \/\/ eslint-disable-next-line no-undef\n    const result = await getColorAnalysis(image)\n    const colorsArray = result.choices[0].message.content\n\n    \/\/ save data to the database\n    const saveStatus = await saveData(image, colorsArray)\n    console.log(saveStatus)\n\n    res.json(result.choices[0])\n})<\/code><\/pre>\n<\/div>\n<h2>Building User Interfaces<\/h2>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/app-screenshot.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/app-screenshot.png\" alt=\"\" width=\"2963\" height=\"1233\" class=\"aligncenter size-full wp-image-31367\" srcset=\"\/wp-content\/uploads\/2025\/02\/app-screenshot.png 2963w, \/wp-content\/uploads\/2025\/02\/app-screenshot-300x125.png 300w, \/wp-content\/uploads\/2025\/02\/app-screenshot-1024x426.png 1024w, \/wp-content\/uploads\/2025\/02\/app-screenshot-768x320.png 768w, \/wp-content\/uploads\/2025\/02\/app-screenshot-1536x639.png 1536w, \/wp-content\/uploads\/2025\/02\/app-screenshot-2048x852.png 2048w, \/wp-content\/uploads\/2025\/02\/app-screenshot-600x250.png 600w\" sizes=\"(max-width: 2963px) 100vw, 2963px\" \/><\/a><\/p>\n<p>The UI comprises two primary user interfaces: <strong>image capture<\/strong> and <strong>color palettes<\/strong>. React.js is utilized in this project to improve component management.<\/p>\n<h3>Image Capture<\/h3>\n<p>The image capture user interface is simply an HTML5 video view. This is the snippet code that shows the main HTML tags used:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">\/\/ WebcamContainer.js\nconst WebcamContainer = ({ onColorsExtracted }) => {\n\n   const captureImage = () => {\n      const context = canvasRef.current.getContext('2d')\n      context.drawImage(videoRef.current, 0, 0, canvasRef.current.width, canvasRef.current.height)\n\n      const base64Image = canvasRef.current.toDataURL('image\/jpeg')\n      processImage(base64Image)\n    }\n    \/\/ code processing here\n\n    return (\n        <div id=\"webcam-container\">\n            <video id=\"webcam\" ref={videoRef} autoPlay playsInline width=\"640\" height=\"480\"><\/video>\n            <canvas id=\"canvas\" ref={canvasRef} width=\"640\" height=\"480\" style={{ display: 'none' }}><\/canvas>\n            <button id=\"capture\" onClick={captureImage}>Capture<\/button>\n            <button id=\"switch-camera\" onClick={switchCamera}>Switch Camera<\/button>\n        <\/div>\n    )\n}\nexport default WebcamContainer<\/code><\/pre>\n<\/div>\n<p>When you click the <strong>Capture<\/strong> button the <code>captureImage()<\/code> function will capture the image on a specific video frame and send it for further processing. The full source code for the image capture user interface is in the <code>WebcamContainer.jsx<\/code> file.<\/p>\n<h3>Color Palettes<\/h3>\n<p>The color palette UI can be created using a series of dynamically colored svg rectangles.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">\/\/ eslint-disable-next-line react\/prop-types\nconst ColorRectangles = ({ colors }) => {\n    return (\n        <svg\n            \n            viewBox=\"0 0 700 100\"\n            className=\"mx-auto\"\n        >\n            {colors.map((color, index) => (\n                <rect\n                    key={index}\n                    x={index * 100}\n                    y=\"0\"\n                    width=\"100\"\n                    height=\"100\"\n                    fill={color}\n                \/>\n            ))}\n        <\/svg>\n    )\n}\n\nexport default ColorRectangles<\/code><\/pre>\n<\/div>\n<p>For example, if the colors array data is:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">['#4B8B3B', '#C4B600', '#7D7D7D', '#E3D4A0', '#2E2E2E', '#F6F1D3', '#A6A6A6']<\/code><\/pre>\n<\/div>\n<p>Then the colors will be rendered on the web as the screenshot below:<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/color-palette-ui.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/color-palette-ui.png\" alt=\"\" width=\"630\" height=\"134\" class=\"aligncenter size-full wp-image-31369\" srcset=\"\/wp-content\/uploads\/2025\/02\/color-palette-ui.png 630w, \/wp-content\/uploads\/2025\/02\/color-palette-ui-300x64.png 300w, \/wp-content\/uploads\/2025\/02\/color-palette-ui-600x128.png 600w\" sizes=\"(max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<h2>Server Routes<\/h2>\n<p>The are four server routes to handle the client request.<\/p>\n<h3>POST <code>\/process-image<\/code><\/h3>\n<p>Process an image for color analysis.<\/p>\n<h3>GET <code>\/colors<\/code><\/h3>\n<p>The <code>\/colors<\/code> route will retrieve all data from the database.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/colors-data.jpeg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/colors-data.jpeg\" alt=\"\" width=\"1539\" height=\"984\" class=\"aligncenter size-full wp-image-31370\" srcset=\"\/wp-content\/uploads\/2025\/02\/colors-data.jpeg 1539w, \/wp-content\/uploads\/2025\/02\/colors-data-300x192.jpeg 300w, \/wp-content\/uploads\/2025\/02\/colors-data-1024x655.jpeg 1024w, \/wp-content\/uploads\/2025\/02\/colors-data-768x491.jpeg 768w, \/wp-content\/uploads\/2025\/02\/colors-data-1536x982.jpeg 1536w, \/wp-content\/uploads\/2025\/02\/colors-data-600x384.jpeg 600w\" sizes=\"(max-width: 1539px) 100vw, 1539px\" \/><\/a><\/p>\n<h3>GET <code>\/colors\/:id<\/code><\/h3>\n<p>Retrieve stored color data based on the ID.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/color-id.jpeg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2025\/02\/color-id.jpeg\" alt=\"\" width=\"1291\" height=\"753\" class=\"aligncenter size-full wp-image-31368\" srcset=\"\/wp-content\/uploads\/2025\/02\/color-id.jpeg 1291w, \/wp-content\/uploads\/2025\/02\/color-id-300x175.jpeg 300w, \/wp-content\/uploads\/2025\/02\/color-id-1024x597.jpeg 1024w, \/wp-content\/uploads\/2025\/02\/color-id-768x448.jpeg 768w, \/wp-content\/uploads\/2025\/02\/color-id-600x350.jpeg 600w\" sizes=\"(max-width: 1291px) 100vw, 1291px\" \/><\/a><\/p>\n<p>The data response for the <code>picture<\/code> field is a <code>Buffer<\/code> type so to process it in the browser, we need to change it into a readable format first.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">\/**\n * Extracting the buffer data\n * Assume the result data name is jsonData \n *\/\nconst bufferData = jsonData[0][1].data;\n\n\/\/ Converting buffer data to Uint8Array object\nconst uint8Array = new Uint8Array(bufferData);\n\n\/\/ Converting Uint8Array to UTF-8 string\nconst utf8String = new TextDecoder('utf-8').decode(uint8Array);\n\nconsole.log(utf8String);<\/code><\/pre>\n<\/div>\n<h3>GET <code>\/delete\/:id<\/code><\/h3>\n<p>Delete specific data in the database by its ID. For example, to delete data with id <code>8900<\/code>:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-js\">http:\/\/localhost:3000\/delete\/8900<\/code><\/pre>\n<\/div>\n<p>Tools like Postman can be used to test APIs.<\/p>\n<h2>SQL Data Test<\/h2>\n<p>To check the data in the database, we can use CLI commands. In this project, we use Ubuntu 20.04 LTS.<\/p>\n<p>Login to the GridDB user:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">sudo su gsadm<\/code><\/pre>\n<\/div>\n<p>and then type this command to enter the GridDB shell:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">gs_sh<\/code><\/pre>\n<\/div>\n<p>In this shell, we can list all containers and run any SQL queries.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">gs[public]> showcontainer\ngs[public]> select * from ColorPalettes;\n1 results (38ms)\ngs[public]> delete from ColorPalettes where id=6609;<\/code><\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we will explore how to extract color palettes from images captured via a webcam using Node.js, GridDB, and OpenAI. By leveraging Node.js for server-side scripting, GridDB for efficient data storage, and OpenAI for advanced image processing, we will create a seamless pipeline to capture images, analyze them, and generate dynamic color palettes. [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":31372,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46825","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Color Palettes Extraction Using Webcam and AI | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"In this tutorial, we will explore how to extract color palettes from images captured via a webcam using Node.js, GridDB, and OpenAI. By leveraging Node.js\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Color Palettes Extraction Using Webcam and AI | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"In this tutorial, we will explore how to extract color palettes from images captured via a webcam using Node.js, GridDB, and OpenAI. By leveraging Node.js\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-14T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-13T20:57:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1463\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"griddb-admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"griddb-admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"Color Palettes Extraction Using Webcam and AI\",\"datePublished\":\"2025-02-14T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:57:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/\"},\"wordCount\":1133,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/\",\"name\":\"Color Palettes Extraction Using Webcam and AI | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg\",\"datePublished\":\"2025-02-14T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:57:14+00:00\",\"description\":\"In this tutorial, we will explore how to extract color palettes from images captured via a webcam using Node.js, GridDB, and OpenAI. By leveraging Node.js\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg\",\"contentUrl\":\"\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg\",\"width\":2560,\"height\":1463},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"caption\":\"griddb-admin\"},\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Color Palettes Extraction Using Webcam and AI | GridDB: Open Source Time Series Database for IoT","description":"In this tutorial, we will explore how to extract color palettes from images captured via a webcam using Node.js, GridDB, and OpenAI. By leveraging Node.js","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/","og_locale":"en_US","og_type":"article","og_title":"Color Palettes Extraction Using Webcam and AI | GridDB: Open Source Time Series Database for IoT","og_description":"In this tutorial, we will explore how to extract color palettes from images captured via a webcam using Node.js, GridDB, and OpenAI. By leveraging Node.js","og_url":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2025-02-14T08:00:00+00:00","article_modified_time":"2025-11-13T20:57:14+00:00","og_image":[{"width":2560,"height":1463,"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg","type":"image\/jpeg"}],"author":"griddb-admin","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"griddb-admin","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/"},"author":{"name":"griddb-admin","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"Color Palettes Extraction Using Webcam and AI","datePublished":"2025-02-14T08:00:00+00:00","dateModified":"2025-11-13T20:57:14+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/"},"wordCount":1133,"commentCount":0,"publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/","url":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/","name":"Color Palettes Extraction Using Webcam and AI | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg","datePublished":"2025-02-14T08:00:00+00:00","dateModified":"2025-11-13T20:57:14+00:00","description":"In this tutorial, we will explore how to extract color palettes from images captured via a webcam using Node.js, GridDB, and OpenAI. By leveraging Node.js","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/color-palettes-extraction-using-webcam-and-ai\/#primaryimage","url":"\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg","contentUrl":"\/wp-content\/uploads\/2025\/02\/webcam-ai-processing-scaled.jpg","width":2560,"height":1463},{"@type":"WebSite","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","caption":"griddb-admin"},"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46825","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/comments?post=46825"}],"version-history":[{"count":1,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46825\/revisions"}],"predecessor-version":[{"id":51483,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46825\/revisions\/51483"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media\/31372"}],"wp:attachment":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media?parent=46825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/categories?post=46825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/tags?post=46825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}