{"id":46789,"date":"2024-02-02T00:00:00","date_gmt":"2024-02-02T08:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/"},"modified":"2026-03-30T11:58:17","modified_gmt":"2026-03-30T18:58:17","slug":"processing-image-data-using-gpt4-vision-node-js-and-griddb","status":"publish","type":"post","link":"https:\/\/www.griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/","title":{"rendered":"Processing Image Data using GPT4-Vision, Node.js, and GridDB"},"content":{"rendered":"<p>This blog will explore how to use GPT-4 Vision to process image data, specifically tabular data from images, and store the results in GridDB. We will build a simple web application using React.js and Node.js that allows users to upload pictures and view the results of GPT-4V&#8217;s image processing.<\/p>\n<h2>Meet the Stacks<\/h2>\n<p>We will use Node.js, GridDB, and OpenAI&#8217;s GPT-4 Vision. For the user interface, we will use React.js.<\/p>\n<h3>GPT-4 Vision<\/h3>\n<p>GPT-4 with Vision, sometimes called GPT-4V, is one of the OpenAI&#8217;s products. It allows the model to take in images and answer questions about them. Language model systems have historically been limited by taking in a single input modality, text. For many use cases, this constrained the areas where models like GPT-4 could be used. You can read more about GPT-4V in their official <a href=\"https:\/\/platform.openai.com\/docs\/guides\/vision\">documentation<\/a>.<\/p>\n<h3>GridDB<\/h3>\n<p>GridDB is an open-source, in-memory NoSQL database optimized for IoT and big data applications. It is a highly scalable database that can handle large volumes of data with high throughput and low latency. GridDB is also ACID compliant and supports SQL-like queries. For more information about GridDB, please visit the <a href=\"https:\/\/griddb.net\/\">GridDB website<\/a>.<\/p>\n<h3>Node.js<\/h3>\n<p>Node.js is an open-source, cross-platform JavaScript runtime environment that allows developers to build scalable network applications. It is built on top of Google&#8217;s V8 JavaScript engine. It uses an event-driven, non-blocking I\/O model that is lightweight and efficient. For more information about Node.js, please visit the <a href=\"https:\/\/nodejs.org\/en\/\">Node.js website<\/a>.<\/p>\n<h3>React.js<\/h3>\n<p>React.js is an open-source JavaScript library for building user interfaces. It is maintained by Facebook and a community of individual developers and companies. React.js allows developers to create reusable UI components that can be used across different applications. For more information about React.js, please visit the <a href=\"https:\/\/reactjs.org\/\">React.js website<\/a>.<\/p>\n<h2>Prerequisites<\/h2>\n<p>This project is tested on Ubuntu 20.04.2 LTS WSL 2. To run this project, you need an OpenAI API key, GridDB, Node.js, and React.js. You can install them by following the instructions below.<\/p>\n<h3>Install Node.js<\/h3>\n<p>To install Node.js v20 LTS on Ubuntu using the package manager, you need to add an additional <code>deb<\/code> repository. Please read and follow this <a href=\"https:\/\/github.com\/nodesource\/distributions?tab=readme-ov-file#ubuntu-versions\">documentation<\/a>. After that, test if the Node.js is installed correctly by typing this command in the terminal:<\/p>\n<div class=\"clipboard\">\n<pre><code>node -v<\/code><\/pre>\n<\/div>\n<h3>Install GridDB<\/h3>\n<p>The GridDB documentation for installation in Ubuntu on WSL can be found <a href=\"https:\/\/docs.griddb.net\/latest\/gettingstarted\/wsl\/#installing-wsl\">here<\/a>. To check if GridDB is installed correctly, you can run the following command:<\/p>\n<div class=\"clipboard\">\n<pre><code>sudo systemctl status gridstore<\/code><\/pre>\n<\/div>\n<p>If GridDB is not started, you can start it using this command:<\/p>\n<div class=\"clipboard\">\n<pre><code>sudo systemctl start gridstore<\/code><\/pre>\n<\/div>\n<h3>OpenAI Account and API Key<\/h3>\n<p>You can get the OpenAI API key by signing up for an account at <a href=\"https:\/\/platform.openai.com\/api-keys\/\">OpenAI<\/a>. To keep your API key safe, you can store it in a <code>.env<\/code> file in the project&#8217;s root directory (more on this later).<\/p>\n<h2>Running the Project<\/h2>\n<p>To get started, you must clone this <a href=\"https:\/\/github.com\/griddbnet\/Blogs\/tree\/image-processing\">repository<\/a> and install the dependencies. You can do this by running the following commands:<\/p>\n<div class=\"clipboard\">\n<pre><code>git clone https:\/\/github.com\/griddbnet\/Blogs.git -- branch image-processing<\/code><\/pre>\n<\/div>\n<p>Change the directory to the project root <code>server<\/code> directory and install the dependencies:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">cd extract-image-table-gpt4-vision\/server\nnpm install<\/code><\/pre>\n<\/div>\n<p>Create a <code>.env<\/code> file in the root directory of the project and write the OpenAI API key. The <code>.env<\/code> file should look like this:<\/p>\n<div class=\"clipboard\">\n<pre><code>OPENAI_API_KEY=[your-api-key]<\/code><\/pre>\n<\/div>\n<p>And add <code>.env<\/code> to the <code>.gitignore<\/code> file to prevent it from being pushed to the repository.<\/p>\n<p>Run the server:<\/p>\n<div class=\"clipboard\">\n<pre><code>npm start<\/code><\/pre>\n<\/div>\n<p>In the browser, go to the default project URL: <code>http:\/\/localhost:5115<\/code> and try to upload an image with tabular data within.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/02\/app-screenshot.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/02\/app-screenshot.png\" alt=\"\" width=\"1077\" height=\"777\" class=\"aligncenter size-full wp-image-29931\" srcset=\"\/wp-content\/uploads\/2024\/02\/app-screenshot.png 1077w, \/wp-content\/uploads\/2024\/02\/app-screenshot-300x216.png 300w, \/wp-content\/uploads\/2024\/02\/app-screenshot-1024x739.png 1024w, \/wp-content\/uploads\/2024\/02\/app-screenshot-768x554.png 768w, \/wp-content\/uploads\/2024\/02\/app-screenshot-600x433.png 600w\" sizes=\"(max-width: 1077px) 100vw, 1077px\" \/><\/a><\/p>\n<p>GPT-4 Vision will process the image and extract the tabular data from it then the tabular data will be displayed on the web page.<\/p>\n<blockquote><p>\n  Please read this <a href=\"#limitations\">note<\/a> about the limitation of this project.\n<\/p><\/blockquote>\n<h2>Project Architecture<\/h2>\n<p>This architecture diagram outlines a data processing and visualization workflow that incorporates GPT-4 Vision, Node.js, and GridDB. Here&#8217;s the breakdown:<\/p>\n<ul>\n<li>The user uploads an image, and <strong>Node.js<\/strong> will call GPT-4 Vision API to process the image. Node.js is the middle layer, handling the data sent and received from the <strong>GPT-4 Vision<\/strong> model.<\/p>\n<\/li>\n<li>The Node.js also communicates with <strong>GridDB<\/strong>, a database for storing and retrieving the data. GridDB would be used to persistently store the processed tabular data.<\/p>\n<\/li>\n<li>\n<p>The display data component at the bottom of the diagram indicates that the application shows the data. It&#8217;s a web interface built using <strong>React.js<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>The project at hand is a web application that is designed to be simple yet powerful. The application is enriched with the advanced capabilities of GPT-4 Vision model, which elevates its functionality to a whole new level.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/02\/project-data-gpt4.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/02\/project-data-gpt4.png\" alt=\"\" width=\"1542\" height=\"910\" class=\"aligncenter size-full wp-image-29934\" srcset=\"\/wp-content\/uploads\/2024\/02\/project-data-gpt4.png 1542w, \/wp-content\/uploads\/2024\/02\/project-data-gpt4-300x177.png 300w, \/wp-content\/uploads\/2024\/02\/project-data-gpt4-1024x604.png 1024w, \/wp-content\/uploads\/2024\/02\/project-data-gpt4-768x453.png 768w, \/wp-content\/uploads\/2024\/02\/project-data-gpt4-1536x906.png 1536w, \/wp-content\/uploads\/2024\/02\/project-data-gpt4-600x354.png 600w\" sizes=\"(max-width: 1542px) 100vw, 1542px\" \/><\/a><\/p>\n<h2>Understanding GPT4-Vision<\/h2>\n<p>The GPT4 Vision model is best at answering general questions about what is present in the images. For example, to describe an image, we can use a simple prompt:<\/p>\n<div class=\"clipboard\">\n<pre><code>\"What's in this image?\"<\/code><\/pre>\n<\/div>\n<p>And then use the prompt in GPT4-Vision API with some image from the internet:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">import OpenAI from \"openai\";\n\nconst openai = new OpenAI();\n\nasync function getImageDescription() {\n  const response = await openai.chat.completions.create({\n    model: \"gpt-4-vision-preview\",\n    messages: [\n      {\n        role: \"user\",\n        content: [\n          { type: \"text\", text: \"What's in this image?\" },\n          {\n            type: \"image_url\",\n            image_url: {\n              \"url\": \"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/d\/dd\/Gfp-wisconsin-madison-the-nature-boardwalk.jpg\/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\",\n            },\n          },\n        ],\n      },\n    ],\n  });\n  console.log(response.choices[0]);\n}<\/code><\/pre>\n<\/div>\n<p>The GPT4 Vision model will process the image based on the prompt and will return the result for further processing.<\/p>\n<p>For our project, we can design a prompt to only recognize the tabular data from the uploaded image. For example, we can use this prompt to extract tabular data from the image:<\/p>\n<div class=\"clipboard\">\n<pre><code>Recreate the table in the image.<\/code><\/pre>\n<\/div>\n<p>Then, in the code, we can use the prompt to only extract the tabular data from the image:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">messages: [\n      {\n        role: \"user\",\n        content: [\n            { type: \"text\", text: \"Recreate table in the image.\" },\n            { type: \"image_url\", \n              image_url: {\n                \"url\": sampleImageAddress,\n              },\n            },\n        ],\n    },\n],<\/code><\/pre>\n<\/div>\n<p>The advantage of using GPT4 Vision from OpenAI is that we don&#8217;t need to train the model to recognize the tabular data from the image. We only need to design a prompt that will be used to process the image and the model is well integrated with other OpenAI models, such as GPT4, to further process the result.<\/p>\n<h2>Integrating GPT4-Vision with Node.js<\/h2>\n<p>We can use Node.js and Express.js to build a simple web server and then create an image processing route that calls GPT4-Vision API after the image is finished and uploaded.<\/p>\n<p>For example, the <code>process-image<\/code> route will accept the uploaded image and then will call the <code>processImageRequest<\/code> function to process the image using OpenAI API:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">app.post('\/process-image', upload.single('image'), async (req, res) => {\n    try {\n        const result = await processImageRequest(req.file.path);\n        \/\/ save the result into the database\n        res.json(result);\n    } catch (error) {\n        res.status(500).send('Error processing image request');\n    }\n});<\/code><\/pre>\n<\/div>\n<p>The <code>processImageRequest<\/code> function is essentially a GPT4 Vision API wrapper function. The code will call the API and then process the image based on the designed prompt earlier:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">async function processImageRequest(filePath) {\n    const imageBuffer = await fs.readFile(filePath);\n    const base64Image = imageBuffer.toString('base64');\n    const encodedImage = `data:image\/jpeg;base64,{${base64Image}}`;\n\n    const response = await openai.chat.completions.create({\n        model: \"gpt-4-vision-preview\",\n        messages: [\n            {\n                role: \"user\",\n                content: [\n                    { type: \"text\", text: tablePrompt },\n                    { type: \"image_url\", image_url: { \"url\": encodedImage } },\n                ],\n            },\n        ],\n        max_tokens: 1024,\n    });\n    return response;\n}<\/code><\/pre>\n<\/div>\n<p>In the code, we use the encoded <code>base64<\/code> format for the image input in GPT4 Vision API. This is because it is easier to reference the image stored in the server&#8217;s local storage than create a public URL for the image.<\/p>\n<p>For a better result, we will feed the result from the <code>processImageRequest<\/code> function into a more general OpenAI model called GPT4 to extract the tabular data only:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">const cleanupPrompt = `I need you to extract the table data from this message and provide the answer in markdown format. Answer only the markdown table data, nothing else. Do not use code blocks. nn`;\n\nasync function cleanupData(data) {\n    const response = await openai.chat.completions.create({\n        model: \"gpt-4-1106-preview\",\n        messages: [\n            {\n                \"role\": \"system\",\n                \"content\": \"you are a smart table data extractor\"\n            },\n            {\n                \"role\": \"user\",\n                \"content\": `${cleanupPrompt} nn${data}`\n            }\n        ],\n        temperature: 1,\n        max_tokens: 2000,\n        top_p: 1,\n        frequency_penalty: 0,\n        presence_penalty: 0,\n    });\n\n    return response;\n}<\/code><\/pre>\n<\/div>\n<p>Essentially, the <code>cleanupData<\/code> function will clean up the result from the <code>processImageRequest<\/code> function by the help of specific prompts. The result will be a markdown table of data that can be displayed on the web page.<\/p>\n<h2>Storing Processed Data in GridDB<\/h2>\n<p>After image processing and data cleanup, we can store the result in GridDB. We will use the <code>saveData<\/code> function, a wrapper function for the <code>put<\/code> operation in GridDB. This function is in the <code>server\/griddbservices.js<\/code> file:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">export async function saveData({ tableData }) {\n    const id = generateRandomID();\n    const data = String(tableData);\n    const packetInfo = [parseInt(id), data];\n    const saveStatus = await GridDB.insert(packetInfo, collectionDb);\n    return saveStatus;\n}<\/code><\/pre>\n<\/div>\n<p>The GridDB container only has two columns: <code>id<\/code> and <code>data<\/code>. The <code>id<\/code> column is used to identify the data, and the <code>data<\/code> column is used to store the markdown table data from GPT4. This snippet code is in the <code>server\/libs\/griddb.cjs<\/code> file.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">function initContainer() {\n    const conInfo = new griddb.ContainerInfo({\n        name: containerName,\n        columnInfoList: [\n            ['id', griddb.Type.INTEGER],\n            ['data', griddb.Type.STRING],\n        ],\n        type: griddb.ContainerType.COLLECTION,\n        rowKey: true,\n    });\n\n    return conInfo;\n}<\/code><\/pre>\n<\/div>\n<p>The <code>saveData<\/code> function can be called in the <code>process-image<\/code> route. The code in the route will check if the result from GPT4 is finished. If the result is finished, the code will clean up the result and then save it to the GridDB database:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">app.post('\/process-image', upload.single('image'), async (req, res) => {\n    log.info('Processing image request')\n    try {\n        const result = await processImageRequest(req.file.path);\n        log.info(`Result: ${JSON.stringify(result)}`);\n\n        if (result.choices[0].finish_reason === 'stop') {\n            const cleanedData = await cleanupData(result.choices[0].message.content);\n            const saveStatus = await saveData({ tableData: JSON.stringify(cleanedData) });\n\n            if (saveStatus.status === 0) {\n                log.error(`Save data to GridDB: ERROR`);\n            } else {\n                log.info(`Save data to GridDB: OK`);\n            }\n            res.json({ result: cleanedData, status: true });\n        } else {\n            res.json({ result, status: false });\n        }\n    } catch (error) {\n        log.error(error);\n        res.status(500).send('Error processing image request');\n    }\n});<\/code><\/pre>\n<\/div>\n<p>The result will be directly displayed on the web page. The reason not to retrieve the data from GridDB is to keep the project simple. You can find the code for the <code>process-image<\/code> route in the <code>server\/server.js<\/code> file.<\/p>\n<p>However, if you want to retrieve the data from GridDB, you can use the <code>get-all-data<\/code> route. This route will retrieve all the data from GridDB.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">app.get('\/get-all-data', async (req, res) => {\n    log.info('Getting all data from GridDB');\n    try {\n        const result = await getAllData();\n        res.json(result);\n    } catch (error) {\n        res.status(500).send('Error getting all data');\n    }\n});<\/code><\/pre>\n<\/div>\n<p>If we run the route in the browser, the server will respond with all the data saved in the GridDB database.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/02\/get-all-data.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/02\/get-all-data.png\" alt=\"\" width=\"904\" height=\"578\" class=\"aligncenter size-full wp-image-29933\" srcset=\"\/wp-content\/uploads\/2024\/02\/get-all-data.png 904w, \/wp-content\/uploads\/2024\/02\/get-all-data-300x192.png 300w, \/wp-content\/uploads\/2024\/02\/get-all-data-768x491.png 768w, \/wp-content\/uploads\/2024\/02\/get-all-data-600x384.png 600w\" sizes=\"(max-width: 904px) 100vw, 904px\" \/><\/a><\/p>\n<h2>Building an End-to-End Application<\/h2>\n<p>The source code for the client or user interface is in the <code>client<\/code> directory. The client is a React.js application.<\/p>\n<h3>Main Application Entry<\/h3>\n<p>The upload user interface is pretty simple. We use the React library for easier user interface development.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/02\/upload-ui.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2024\/02\/upload-ui.png\" alt=\"\" width=\"1129\" height=\"742\" class=\"aligncenter size-full wp-image-29935\" srcset=\"\/wp-content\/uploads\/2024\/02\/upload-ui.png 1129w, \/wp-content\/uploads\/2024\/02\/upload-ui-300x197.png 300w, \/wp-content\/uploads\/2024\/02\/upload-ui-1024x673.png 1024w, \/wp-content\/uploads\/2024\/02\/upload-ui-768x505.png 768w, \/wp-content\/uploads\/2024\/02\/upload-ui-600x394.png 600w\" sizes=\"(max-width: 1129px) 100vw, 1129px\" \/><\/a><\/p>\n<p>Here is the main entry code for the app:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">import React, { useState } from 'react';\nimport ImageUploader from '.\/ImageUploader';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport rehypeRaw from 'rehype-raw';\n\nconst App = () => {\n    const [markdown, setMarkdown] = useState('');\n\n    const handleMarkdownFetch = (markdownData) => {\n        setMarkdown(markdownData.result.choices[0].message.content);\n    };\n\n    return (\n    <div className=\"flex flex-col items-center justify-center min-h-screen space-y-4 bg-white\">\n        <h1 className=\"text-3xl\">Extract Table From Image Using GPT4<\/h1>\n        <div className=\"w-full max-w-4xl mx-auto py-12\">\n            <ImageUploader onMarkdownFetch={handleMarkdownFetch} \/>\n            <div className=\"flex items-center justify-center overflow-x-auto w-full py-12\">\n                <ReactMarkdown className=\"markdown\" remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>{markdown}<\/ReactMarkdown>\n            <\/div>\n        <\/div>\n    <\/div>\n);\n\nexport default App;<\/code><\/pre>\n<\/div>\n<p>The main application entry consists of two components: <code>&lt;ImageUploader&gt;<\/code> and <code>&lt;ReactMarkdown&gt;<\/code>. The <code>&lt;ImageUploader&gt;<\/code> component is responsible for uploading the image to the server, and it returns a result that will be handled by any function that is attached to the <code>onMarkdownFetch<\/code> prop and then the markdown data will be rendered in the <code>&lt;ReactMarkdown&gt;<\/code> component.<\/p>\n<h3>Image Uploader<\/h3>\n<p>The <code>&lt;ImageUploader&gt;<\/code> component code resides in the <code>client\/src\/ImageUploader.jsx<\/code> file. The handler for the image upload is in the <code>handleUpload<\/code> function. This function will post the image to the <code>\/process-image<\/code> route in the server, and the result from the server will be handled by the <code>onMarkdownFetch<\/code> prop.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">const handleUpload = async () => {\n        if (selectedFile && !uploading) { \n            setUploading(true); \n\n            const formData = new FormData();\n            formData.append('image', selectedFile);\n\n            try {\n                const response = await fetch('\/process-image', {\n                    method: 'POST',\n                    body: formData,\n                });\n                if (!response.ok) {\n                    throw new Error('Network response was not ok');\n                }\n                const markdownData = await response.json();\n                props.onMarkdownFetch(markdownData);\n            } catch (error) {\n                console.error('Error posting image:', error);\n            } finally {\n                setUploading(false);\n            }\n        } else {\n            alert('Please select an image first.');\n        }\n    };<\/code><\/pre>\n<\/div>\n<h3>Markdown Renderer<\/h3>\n<p>Luckily, there is a React component in the npm package readily used for rendering markdown purposes. The <a href=\"https:\/\/github.com\/remarkjs\/react-markdown\">react-markdown<\/a> component is easy to use and integrate with any React application.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">import ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport rehypeRaw from 'rehype-raw';\n\n...\n<ReactMarkdown className=\"markdown\" remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>{markdown}<\/ReactMarkdown>\n...<\/code><\/pre>\n<\/div>\n<p>Also, we need to add <code>remark-gfm<\/code> and <code>rehype-raw<\/code> plugins. The <code>remark-gfm<\/code> plugin is used to render the markdown table, and the <code>rehype-raw<\/code> plugin is used to render the markdown table as a raw HTML element so we can add style to it later.<\/p>\n<h2>Limitations<\/h2>\n<p>This project is a simple demonstration of how to use GPT4 Vision to process image data and store the result in GridDB. There are many ways to improve this project.<\/p>\n<p>Currently, the project only supports a clear and clean image containing only a table in it. With the current state of the GPT4 Vision model, which is still in preview, it is not possible to process a noisy image, such as an image containing table data mixed with other text or images. The best way to improve this project is to crop the image containing the table data and then process it using GPT4 Vision.<\/p>\n<h2>References<\/h2>\n<ul>\n<li><a href=\"https:\/\/platform.openai.com\/docs\/guides\/vision\">GPT4 Vision guide<\/a>.<\/li>\n<li><a href=\"https:\/\/platform.openai.com\/docs\/api-reference\/chat\">GPT4 Vision API documentation<\/a>.<\/li>\n<li><a href=\"https:\/\/docs.griddb.net\/\">GridDB documentation<\/a>.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This blog will explore how to use GPT-4 Vision to process image data, specifically tabular data from images, and store the results in GridDB. We will build a simple web application using React.js and Node.js that allows users to upload pictures and view the results of GPT-4V&#8217;s image processing. Meet the Stacks We will use [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":29932,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46789","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>Processing Image Data using GPT4-Vision, Node.js, and GridDB | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"This blog will explore how to use GPT-4 Vision to process image data, specifically tabular data from images, and store the results in GridDB. We will\" \/>\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\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Processing Image Data using GPT4-Vision, Node.js, and GridDB | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"This blog will explore how to use GPT-4 Vision to process image data, specifically tabular data from images, and store the results in GridDB. We will\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/\" \/>\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=\"2024-02-02T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-30T18:58:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.griddb.net\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1120\" \/>\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=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"Processing Image Data using GPT4-Vision, Node.js, and GridDB\",\"datePublished\":\"2024-02-02T08:00:00+00:00\",\"dateModified\":\"2026-03-30T18:58:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/\"},\"wordCount\":1647,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/\",\"name\":\"Processing Image Data using GPT4-Vision, Node.js, and GridDB | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg\",\"datePublished\":\"2024-02-02T08:00:00+00:00\",\"dateModified\":\"2026-03-30T18:58:17+00:00\",\"description\":\"This blog will explore how to use GPT-4 Vision to process image data, specifically tabular data from images, and store the results in GridDB. We will\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg\",\"contentUrl\":\"\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg\",\"width\":2000,\"height\":1120},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.griddb.net\/en\/#website\",\"url\":\"https:\/\/www.griddb.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:\/\/www.griddb.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.griddb.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.griddb.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/www.griddb.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.griddb.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:\/\/www.griddb.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:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.griddb.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:\/\/www.griddb.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Processing Image Data using GPT4-Vision, Node.js, and GridDB | GridDB: Open Source Time Series Database for IoT","description":"This blog will explore how to use GPT-4 Vision to process image data, specifically tabular data from images, and store the results in GridDB. We will","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\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/","og_locale":"en_US","og_type":"article","og_title":"Processing Image Data using GPT4-Vision, Node.js, and GridDB | GridDB: Open Source Time Series Database for IoT","og_description":"This blog will explore how to use GPT-4 Vision to process image data, specifically tabular data from images, and store the results in GridDB. We will","og_url":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2024-02-02T08:00:00+00:00","article_modified_time":"2026-03-30T18:58:17+00:00","og_image":[{"width":2000,"height":1120,"url":"https:\/\/www.griddb.net\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.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":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/"},"author":{"name":"griddb-admin","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"Processing Image Data using GPT4-Vision, Node.js, and GridDB","datePublished":"2024-02-02T08:00:00+00:00","dateModified":"2026-03-30T18:58:17+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/"},"wordCount":1647,"commentCount":0,"publisher":{"@id":"https:\/\/www.griddb.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/","url":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/","name":"Processing Image Data using GPT4-Vision, Node.js, and GridDB | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/www.griddb.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg","datePublished":"2024-02-02T08:00:00+00:00","dateModified":"2026-03-30T18:58:17+00:00","description":"This blog will explore how to use GPT-4 Vision to process image data, specifically tabular data from images, and store the results in GridDB. We will","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/processing-image-data-using-gpt4-vision-node-js-and-griddb\/#primaryimage","url":"\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg","contentUrl":"\/wp-content\/uploads\/2024\/02\/blog-gpt4-cover.jpg","width":2000,"height":1120},{"@type":"WebSite","@id":"https:\/\/www.griddb.net\/en\/#website","url":"https:\/\/www.griddb.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:\/\/www.griddb.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.griddb.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.griddb.net\/en\/#organization","name":"Fixstars","url":"https:\/\/www.griddb.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.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:\/\/www.griddb.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:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.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:\/\/www.griddb.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/46789","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/comments?post=46789"}],"version-history":[{"count":2,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/46789\/revisions"}],"predecessor-version":[{"id":55109,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/46789\/revisions\/55109"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media\/29932"}],"wp:attachment":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media?parent=46789"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/categories?post=46789"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/tags?post=46789"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}