{"id":21662383,"url":"https://github.com/orengrinker/jstextfromimage","last_synced_at":"2026-02-10T17:32:38.585Z","repository":{"id":264057883,"uuid":"892209907","full_name":"OrenGrinker/jsTextFromImage","owner":"OrenGrinker","description":"Get descriptions of images using OpenAI's GPT-4 Vision models, Azure OpenAI, and Anthropic Claude in an easy way.","archived":false,"fork":false,"pushed_at":"2024-11-27T17:29:27.000Z","size":355,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-16T22:19:23.760Z","etag":null,"topics":["anthropic-claude","azure-openai","azure-openai-api","claude-3-5-sonnet","claude-api","image-processing","npm","npm-package","openai-api"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OrenGrinker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-11-21T17:39:49.000Z","updated_at":"2024-11-27T17:29:36.000Z","dependencies_parsed_at":"2025-04-11T23:44:00.395Z","dependency_job_id":"43d96847-a654-4ec7-ba88-b14378e06805","html_url":"https://github.com/OrenGrinker/jsTextFromImage","commit_stats":null,"previous_names":["orengrinker/jstextfromimage"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/OrenGrinker/jsTextFromImage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrenGrinker%2FjsTextFromImage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrenGrinker%2FjsTextFromImage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrenGrinker%2FjsTextFromImage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrenGrinker%2FjsTextFromImage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OrenGrinker","download_url":"https://codeload.github.com/OrenGrinker/jsTextFromImage/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrenGrinker%2FjsTextFromImage/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261791282,"owners_count":23210117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic-claude","azure-openai","azure-openai-api","claude-3-5-sonnet","claude-api","image-processing","npm","npm-package","openai-api"],"created_at":"2024-11-25T10:15:58.632Z","updated_at":"2026-02-10T17:32:38.549Z","avatar_url":"https://github.com/OrenGrinker.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSTextFromImage\n\n![npm Version](https://img.shields.io/npm/v/jstextfromimage)\n![TypeScript](https://img.shields.io/npm/types/jstextfromimage)\n![License](https://img.shields.io/npm/l/jstextfromimage)\n![Downloads](https://img.shields.io/npm/dm/jstextfromimage)\n![Node Version](https://img.shields.io/node/v/jstextfromimage)\n\nA powerful TypeScript/JavaScript library for obtaining detailed descriptions of images using various AI models including OpenAI's GPT-4 Vision, Azure OpenAI, and Anthropic Claude. Supports image URLs with batch processing capabilities.\n\n## 🌟 Key Features\n\n- 🤖 **Multiple AI Providers**: Support for OpenAI, Azure OpenAI, and Anthropic Claude\n- 🌐 **URL Support**: Process images from URLs\n- 📦 **Batch Processing**: Process multiple images concurrently\n- 📝 **TypeScript First**: Built with TypeScript for excellent type safety\n- 🔄 **Async/Await**: Modern Promise-based API\n- 🔑 **Flexible Auth**: Multiple authentication methods including environment variables\n- 🛡️ **Error Handling**: Comprehensive error handling\n\n## 📦 Installation\n\n```bash\nnpm install jstextfromimage\n```\n\n## 🚀 Quick Start\n\nYou can use the services either with environment variables or direct initialization.\n\n### Using Environment Variables\n\n```typescript\nimport { openai, claude, azureOpenai } from 'jstextfromimage';\n\n// Services will automatically use environment variables\nconst description = await openai.getDescription('https://example.com/image.jpg');\n```\n\n### Direct Initialization\n\n```typescript\nimport { OpenAIService, ClaudeService, AzureOpenAIService } from 'jstextfromimage';\n\n// OpenAI custom instance\nconst customOpenAI = new OpenAIService('your-openai-api-key');\n\n// Claude custom instance\nconst customClaude = new ClaudeService('your-claude-api-key');\n\n// Azure OpenAI custom instance\nconst customAzure = new AzureOpenAIService({\n  apiKey: 'your-azure-api-key',\n  endpoint: 'your-azure-endpoint',\n  deploymentName: 'your-deployment-name'\n});\n```\n\n### OpenAI Service\n\n```typescript\nimport { openai } from 'jstextfromimage';\n\n// Single image analysis\nconst description = await openai.getDescription('https://example.com/image.jpg', {\n  prompt: \"Describe the main elements of this image\",\n  maxTokens: 500,\n  model: 'gpt-4o'\n});\n\n// Batch processing\nconst imageUrls = [\n  'https://example.com/image1.jpg',\n  'https://example.com/image2.jpg',\n  'https://example.com/image3.jpg'\n];\n\nconst results = await openai.getDescriptionBatch(imageUrls, {\n  prompt: \"Analyze this image in detail\",\n  maxTokens: 300,\n  concurrency: 2,\n  model: 'gpt-4o'\n});\n\n// Process results\nresults.forEach(result =\u003e {\n  if (result.error) {\n    console.error(`Error processing ${result.imageUrl}: ${result.error}`);\n  } else {\n    console.log(`Description for ${result.imageUrl}: ${result.description}`);\n  }\n});\n```\n\n### Claude Service\n\n```typescript\nimport { claude } from 'jstextfromimage';\n\n// Single image analysis\nconst description = await claude.getDescription('https://example.com/artwork.jpg', {\n  prompt: \"Analyze this artwork, including style and composition\",\n  maxTokens: 1000,\n  model: 'claude-3-sonnet-20240229'\n});\n\n// Batch processing\nconst artworkUrls = [\n  'https://example.com/artwork1.jpg',\n  'https://example.com/artwork2.jpg'\n];\n\nconst analyses = await claude.getDescriptionBatch(artworkUrls, {\n  prompt: \"Provide a detailed art analysis\",\n  maxTokens: 800,\n  concurrency: 2,\n  model: 'claude-3-sonnet-20240229'\n});\n```\n\n### Azure OpenAI Service\n\n```typescript\nimport { azureOpenai } from 'jstextfromimage';\n\n// Single image analysis\nconst description = await azureOpenai.getDescription('https://example.com/scene.jpg', {\n  prompt: \"Describe this scene in detail\",\n  maxTokens: 400,\n  systemPrompt: \"You are an expert in visual analysis.\"\n});\n\n// Batch processing\nconst sceneUrls = [\n  'https://example.com/scene1.jpg',\n  'https://example.com/scene2.jpg'\n];\n\nconst analyses = await azureOpenai.getDescriptionBatch(sceneUrls, {\n  prompt: \"Analyze the composition and mood\",\n  maxTokens: 500,\n  concurrency: 3,\n  systemPrompt: \"You are an expert cinematographer.\"\n});\n```\n\n## 💡 Configuration\n\n### Default Values\n\n```typescript\n// OpenAI defaults\n{\n  model: 'gpt-4o',\n  maxTokens: 300,\n  prompt: \"What's in this image?\",\n  concurrency: 3  // for batch processing\n}\n\n// Claude defaults\n{\n  model: 'claude-3-sonnet-20240229',\n  maxTokens: 300,\n  prompt: \"What's in this image?\",\n  concurrency: 3\n}\n\n// Azure OpenAI defaults\n{\n  maxTokens: 300,\n  prompt: \"What's in this image?\",\n  systemPrompt: \"You are a helpful assistant.\",\n  concurrency: 3\n}\n```\n\n### Local File Support\n\n```typescript\nimport { openai } from 'jstextfromimage';\n\n// Single local file\nconst description = await openai.getDescription('/path/to/local/image.jpg', {\n  prompt: \"Describe this image\",\n  maxTokens: 300,\n  model: 'gpt-4o'\n});\n\n// Mix of local files and URLs in batch processing\nconst images = [\n  '/path/to/local/image1.jpg',\n  'https://example.com/image2.jpg',\n  '/path/to/local/image3.png'\n];\n\nconst results = await openai.getDescriptionBatch(images, {\n  prompt: \"Analyze each image\",\n  maxTokens: 300,\n  concurrency: 2\n});\n```\n\n### Environment Variables\n\n```env\n# OpenAI\nOPENAI_API_KEY=your-openai-api-key\n\n# Claude\nANTHROPIC_API_KEY=your-claude-api-key\n\n# Azure OpenAI\nAZURE_OPENAI_API_KEY=your-azure-api-key\nAZURE_OPENAI_ENDPOINT=your-azure-endpoint\nAZURE_OPENAI_DEPLOYMENT=your-deployment-name\n```\n\n### Options Interfaces\n\n```typescript\n// Base options for all services\ninterface BaseOptions {\n  prompt?: string;\n  maxTokens?: number;\n  concurrency?: number; // For batch processing\n}\n\n// OpenAI specific options\ninterface OpenAIOptions extends BaseOptions {\n  model?: string;\n}\n\n// Claude specific options\ninterface ClaudeOptions extends BaseOptions {\n  model?: string;\n}\n\n// Azure OpenAI specific options\ninterface AzureOpenAIOptions extends BaseOptions {\n  systemPrompt?: string;\n}\n\n// Azure OpenAI configuration\ninterface AzureOpenAIConfig {\n  apiKey?: string;\n  endpoint?: string;\n  deploymentName?: string;\n  apiVersion?: string;\n}\n\n// Batch processing results\ninterface BatchResult {\n  imageUrl: string;\n  description: string;\n  error?: string;\n}\n```\n\n## 🔍 Error Handling Examples\n\n```typescript\n// Single image with error handling\ntry {\n  const description = await openai.getDescription(imageUrl, {\n    maxTokens: 300\n  });\n  console.log(description);\n} catch (error) {\n  console.error('Failed to process image:', error);\n}\n\n// Batch processing with retry\nasync function processWithRetry(imageUrls: string[], maxRetries = 3) {\n  const results = await openai.getDescriptionBatch(imageUrls, {\n    maxTokens: 300,\n    concurrency: 2\n  });\n  \n  // Handle failed items with retry\n  const failedItems = results.filter(r =\u003e r.error);\n  let retryCount = 0;\n  \n  while (failedItems.length \u003e 0 \u0026\u0026 retryCount \u003c maxRetries) {\n    const retryUrls = failedItems.map(item =\u003e item.imageUrl);\n    const retryResults = await openai.getDescriptionBatch(retryUrls, {\n      maxTokens: 300,\n      concurrency: 1 // Lower concurrency for retries\n    });\n    \n    // Update results with successful retries\n    retryResults.forEach(result =\u003e {\n      if (!result.error) {\n        const index = results.findIndex(r =\u003e r.imageUrl === result.imageUrl);\n        if (index !== -1) {\n          results[index] = result;\n        }\n      }\n    });\n    \n    retryCount++;\n  }\n  \n  return results;\n}\n```\n\n## 🛠️ Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build the project\nnpm run build\n\n# Run linting\nnpm run lint\n```\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -am 'feat: add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## 📝 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 💬 Support\n\nFor support, please [open an issue](https://github.com/OrenGrinker/jstextfromimage/issues/new) on GitHub.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forengrinker%2Fjstextfromimage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forengrinker%2Fjstextfromimage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forengrinker%2Fjstextfromimage/lists"}