{"id":37234669,"url":"https://github.com/phpcfdi/image-captcha-resolver","last_synced_at":"2026-01-15T04:00:14.943Z","repository":{"id":46058096,"uuid":"389522685","full_name":"phpcfdi/image-captcha-resolver","owner":"phpcfdi","description":"Conectores para resolver captchas de imágenes","archived":false,"fork":false,"pushed_at":"2025-09-13T20:37:49.000Z","size":203,"stargazers_count":8,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-14T14:36:58.397Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phpcfdi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-07-26T05:53:23.000Z","updated_at":"2025-09-13T20:00:50.000Z","dependencies_parsed_at":"2025-09-13T22:04:47.145Z","dependency_job_id":"1f58f522-b0b9-4ae1-b6b8-36f505675a41","html_url":"https://github.com/phpcfdi/image-captcha-resolver","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/phpcfdi/image-captcha-resolver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpcfdi%2Fimage-captcha-resolver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpcfdi%2Fimage-captcha-resolver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpcfdi%2Fimage-captcha-resolver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpcfdi%2Fimage-captcha-resolver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phpcfdi","download_url":"https://codeload.github.com/phpcfdi/image-captcha-resolver/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpcfdi%2Fimage-captcha-resolver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28442357,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:55:22.719Z","status":"online","status_checked_at":"2026-01-15T02:00:08.019Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-01-15T04:00:14.058Z","updated_at":"2026-01-15T04:00:14.865Z","avatar_url":"https://github.com/phpcfdi.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# phpcfdi/image-captcha-resolver\n\n[![Source Code][badge-source]][source]\n[![Packagist PHP Version Support][badge-php-version]][php-version]\n[![Discord][badge-discord]][discord]\n[![Latest Version][badge-release]][release]\n[![Software License][badge-license]][license]\n[![Build Status][badge-build]][build]\n[![Reliability][badge-reliability]][reliability]\n[![Maintainability][badge-maintainability]][maintainability]\n[![Code Coverage][badge-coverage]][coverage]\n[![Violations][badge-violations]][violations]\n[![Total Downloads][badge-downloads]][downloads]\n\n\u003e Conectores para resolver captchas de imágenes\n\n:us: The documentation of this project is in spanish as this is the natural language for the intended audience.\n\n## Acerca de phpcfdi/image-captcha-resolver\n\nEsta librería contiene conectores con algunos servicios populares o de prueba para resolver captchas.\n\nEs utilizado en algunos proyectos de [PhpCfdi](https://github.com/phpcfdi).\n\n## Instalación\n\nUsa [composer](https://getcomposer.org/)\n\n```shell\ncomposer require phpcfdi/image-captcha-resolver\n```\n\nEs posible que para su correcta implementación requiera también instalar algunos paquetes adicionales.\nVea \u003chttps://docs.php-http.org/en/latest/clients.html\u003e\n\n```shell\n# uso de guzzle, con el adaptador del cliente y su contructor de request y response\ncomposer require guzzlehttp/guzzle php-http/guzzle7-adapter guzzlehttp/psr7\n\n# uso de symfony http client con nyholm/psr7 como constructor de request y response\ncomposer require symfony/http-client nyholm/psr7\n\n# uso de cliente basado en curl con laminas/laminas-diactoros como constructor de request y response\ncomposer require php-http/curl-client laminas/laminas-diactoros\n```\n\nSin embargo, si lo que está desarrollando es una librería debería usar como dependencia de cliente\nel paquete `php-http/mock-client` y cualquier fábrica de mensajes (en `composer.json:require-dev`).\n\n## Uso básico\n\n### Llamar a resolver un captcha\n\nPara este ejemplo se asume que ya existe un resolvedor de captchas en `$resolver`\ny que la imagen del captcha se encuentra como imagen embedida y su contenido en `$theImgElementSrcAtributte`.\n\n```php\n\u003c?php declare(strict_types=1);\n\nuse PhpCfdi\\ImageCaptchaResolver\\CaptchaImage;\nuse PhpCfdi\\ImageCaptchaResolver\\CaptchaResolverInterface;\nuse PhpCfdi\\ImageCaptchaResolver\\UnableToResolveCaptchaException;\n\n/**\n * @var string $theImgElementSrcAtributte\n * @var CaptchaResolverInterface $resolver\n */\n\n$image = CaptchaImage::newFromInlineHtml($theImgElementSrcAtributte);\n\ntry {\n    $answer = $resolver-\u003eresolve($image);\n} catch (UnableToResolveCaptchaException $exception) {\n    echo 'No se pudo resolver el captcha', PHP_EOL;\n    return;\n}\n\necho \"Respuesta del captcha: {$answer-\u003egetValue()}\", PHP_EOL;\n```\n\n### Creación de un resolvedor de captchas basado en Anti-Captcha\n\nPara crear el resolvedor se puede hacer de dos formas: de manera específica y por descubrimiento.\n\nServicio: \u003chttps://anti-captcha.com\u003e\n\n```php\n\u003c?php declare(strict_types=1);\n\nuse PhpCfdi\\ImageCaptchaResolver\\Resolvers\\AntiCaptchaResolver;\nuse PhpCfdi\\ImageCaptchaResolver\\Timer\\Timer;\n\n/**\n * @var string $clientKey La clave de cliente para conectarse a anti-captcha \n */\n\n// Se puede crear el resolvedor usando los parámetros predefinidos\n$resolverDefault = AntiCaptchaResolver::create($clientKey);\n\n// O especificando parámetros funcionales\n$resolverWithSettings = AntiCaptchaResolver::create(\n    $clientKey,\n    5, // segundos antes de intentar leer la respuesta\n    60, // segundos antes de considerar que el captcha no tiene solución\n    500 // milisegundos antes de reintentar obtener la respuesta\n);\n\n// O directamente creando los objetos\n$resolverConstructed = new AntiCaptchaResolver(\n    new AntiCaptchaResolver\\AntiCaptchaConnector($clientKey),\n    new Timer(4, 60, 500)\n);\n```\n\n### Creación de un resolvedor de captchas basado en Local Captcha Resolver\n\nPara crear el resolvedor se puede hacer de dos formas: de manera específica y por descubrimiento.\n\nServicio: \u003chttps://github.com/eclipxe13/captcha-local-resolver\u003e\n\n```php\n\u003c?php declare(strict_types=1);\n\nuse PhpCfdi\\ImageCaptchaResolver\\Resolvers\\CaptchaLocalResolver;\nuse PhpCfdi\\ImageCaptchaResolver\\Timer\\Timer;\n\n/**\n * @var string $baseUrl La dirección donde está corriendo el servicio, como http://localhost:9095 \n */\n\n// Se puede crear el resolvedor usando los parámetros predefinidos\n$resolverDefault = CaptchaLocalResolver::create($baseUrl);\n\n// O especificando parámetros funcionales\n$resolverWithSettings = CaptchaLocalResolver::create(\n    $baseUrl,\n    5, // segundos antes de intentar leer la respuesta\n    60, // segundos antes de considerar que el captcha no tiene solución\n    500 // milisegundos antes de reintentar obtener la respuesta\n);\n\n// O directamente creando los objetos\n$resolverConstructed = new CaptchaLocalResolver(\n    new CaptchaLocalResolver\\CaptchaLocalResolverConnector($baseUrl),\n    new Timer(4, 60, 500)\n);\n```\n\n### Creación de un resolvedor de captchas basado en línea de comandos\n\nLa implementación dependerá siempre de la herramienta que se esté utilizando, es probable que fabrique\nsu propio punto de entrada a la herramienta para que devuelva el *exit code* correcto y la respuesta.\n\nEsta herramienta podría ser útil en caso de que el captcha se pueda resolver utilizando alguna herramienta\ncomo [`tesseract`](https://github.com/tesseract-ocr/tesseract).\n\nEl siguiente ejemplo supone que tiene la imagen del captcha a resolver en `$image` y que existe un commando\nllamado `my-captcha-breaker` que se le entrega una imagen y devuelve en el último renglón de la salida\nla respuesta del captcha.\n\n```php\n\u003c?php declare(strict_types=1);\n\nuse PhpCfdi\\ImageCaptchaResolver\\CaptchaImageInterface;\nuse PhpCfdi\\ImageCaptchaResolver\\Resolvers\\CommandLineResolver;\nuse PhpCfdi\\ImageCaptchaResolver\\UnableToResolveCaptchaException;\n\n/**\n * @var CaptchaImageInterface $image \n */\n\n$resolver = CommandLineResolver::create(explode(' ', 'my-captcha-breaker --in {file} --stdout'));\n\ntry {\n    $answer = $resolver-\u003eresolve($image);\n} catch (UnableToResolveCaptchaException $exception) {\n    echo 'No se pudo resolver el captcha: ', $exception-\u003egetMessage(), PHP_EOL;\n    return;\n}\n\necho $answer, PHP_EOL;\n```\n\n## Resolvedores\n\n### Multiresolvedor\n\nEl resolvedor `MultiResolver` es en sí mismo un resolvedor que intenta resolver el captcha usando un conjunto\npredefinido de resolvedores. Podría ser útil para intentar resolver utilizando diferentes estrategias\no reintentando con un mismo resolvedor el número de veces en las que esté incluído.\n\n### Resolvedores para pruebas\n\nEl resolvedor `CaptchaLocalResolver` usa servicio de resolución de captchas local y es comúnmente utilizado para pruebas.\n\nTambién podría usar el resolvedor `ConsoleResolver` en donde se almacena en un archivo predefinido\nla imagen del captcha a resolver y se espera que escriba la ventana en la misma terminal donde está\nejecutando el proceso. Solo es útil si puede escribir la respuesta. Si no se recibe la respuesta\nen un tiempo predeterminado el resolvedor fallará lo tomará como una respuesta vacía.\n\nSi está haciendo pruebas unitarias, la mejor alternativa es usar el resolvedor `MockResolver`, que se construye\ncon respuestas prestablecidas `CaptchaAnswerInterface` o excepciones `UnableToResolveCaptchaException` y falla con una\nexcepción `OutOfRangeException` si se le pide una respuesta y ya no tiene más.\n\n### Nuevos resolvedores\n\nSi ya tienes contratado un servicio de solución de captchas o deseas implementar uno, por ejemplo,\nbasado en `tesseract`, debes implementar la interfaz `ResolverInterface` en tu proyecto.\n\nSi el resolvedor puede beneficiar a toda la comunidad entonces haz tu solicitud de que se incluya\nen esta librería y con gusto lo evaluaremos, tomando en cuenta las dependencias y las pruebas.\n\nSi el servicio requiere de registrar una nueva cuenta, por favor ponte en contacto con nosotros\ny podemos crear el resolvedor. Considera que será necesario que patrocines la suscripción\npara poder hacer pruebas de funcionamiento punto a punto.\n\n## Especificación de clases e interfaces\n\n### `CaptchaImage`\n\nContiene la imagen en `base64` de la imagen, se puede construir desde un archivo, desde datos binarios,\ndesde datos binarios codificados como `base64` o desde un texto de imagen html embedido.\n\n- `static CaptchaImage::newFromFile(string $filename): self`\n- `static CaptchaImage::newFromBinary(string $contents): self`\n- `static CaptchaImage::newFromBase64(string $contents): self`\n- `static CaptchaImage::newFromInlineHtml(string $contents): self`\n\nTambién contiene métodos para expresar la imagen u obtener el tipo MIME:\n\n- `CaptchaImage::asBinary(): string`\n- `CaptchaImage::asBase64(): string`\n- `CaptchaImage::asBinary(): string`\n- `CaptchaImage::asInlineHtml(): string`\n- `CaptchaImage::getMimeType(): string`\n\nTambién se puede expresar como JSON o como string pues implementa `Stringable` y `JsonSerializable`\ny si lo desea, puede establecer su propia implementación usando `CaptchaImageInterface`.\n\n### `CaptchaResolverInterface`\n\nContiene un único método de resolución en donde toma un `CaptchaImageInterface` y entrega un `CaptchaAnswer`:\n`CaptchaResolverInterface::resolve(CaptchaImageInterface $image): CaptchaAnswerInterface`.\n\nHay diferentes implementaciones y se pueden agregar más a esta librería o en una librería independiente.\n\n### `CaptchaAnswer`\n\nContiene la respuesta del captcha como un valor de texto, no puede ser una cadena vacía.\n\nLa respuesta se obtiene con el método `CaptchaAnswer::getValue(): string`.\n\nY se puede comparar contra cualquier otro valor usando `CaptchaAnswer::equalsTo($value): bool`.\n\nTambién se puede expresar como JSON o como string pues implementa `Stringable` y `JsonSerializable`\ny si lo desea, puede establecer su propia implementación usando `CaptchaAnswerInterface`.\n\n### `HttpClientInterface` y `HttpClient`\n\nEste método es un adaptador para facilitar las comunicaciones de HTTP con el exterior.\n\nLa implementación actual contiene muy pocos métodos y serán agregados nuevos conforme se necesite.\n\nUtiliza los estándares PSR-18 *HTTP Client*, y PSR-17 *HTTP Factories* que usan el PSR-7 *HTTP message interfaces*.\nRequieren de un cliente http que implemente el PSR-18 y de una librería que implemente PSR-17 para construir los\nmensajes de tipo `Request` o `Response`.\n\nPara que sea fácil poder crear el objeto, se usa el paquete de HTTPlug Discovery\n[`php-http/discovery`](https://docs.php-http.org/en/latest/discovery.html) que\npermite encontrar implementaciones instaladas y utilizarlas.\n\nEl método `HttpClient::discovery()` es el que se utiliza de forma predeterminada para construir el objeto,\naunque también se puede crear utilizando el constructor y entregando los objetos necesarios.\n\n## Soporte\n\nPuedes obtener soporte abriendo un ticket en Github.\n\nAdicionalmente, esta librería pertenece a la comunidad [PhpCfdi](https://www.phpcfdi.com), así que puedes usar los\nmismos canales de comunicación para obtener ayuda de algún miembro de la comunidad.\n\n## Compatibilidad\n\nEsta librería se mantendrá compatible con al menos la versión con\n[soporte activo de PHP](https://www.php.net/supported-versions.php) más reciente.\n\nTambién utilizamos [Versionado Semántico 2.0.0](docs/SEMVER.md) por lo que puedes usar esta librería\nsin temor a romper tu aplicación.\n\n## Contribuciones\n\nLas contribuciones con bienvenidas. Por favor lee [CONTRIBUTING][] para más detalles\ny recuerda revisar el archivo de tareas pendientes [TODO][] y el archivo [CHANGELOG][].\n\n## Copyright and License\n\nThe `phpcfdi/image-captcha-resolver` library is copyright © [PhpCfdi](https://www.phpcfdi.com/)\nand licensed for use under the MIT License (MIT). Please see [LICENSE][] for more information.\n\n[contributing]: https://github.com/phpcfdi/image-captcha-resolver/blob/main/CONTRIBUTING.md\n[changelog]: https://github.com/phpcfdi/image-captcha-resolver/blob/main/docs/CHANGELOG.md\n[todo]: https://github.com/phpcfdi/image-captcha-resolver/blob/main/docs/TODO.md\n\n[source]: https://github.com/phpcfdi/image-captcha-resolver\n[php-version]: https://packagist.org/packages/phpcfdi/image-captcha-resolver\n[discord]: https://discord.gg/aFGYXvX\n[release]: https://github.com/phpcfdi/image-captcha-resolver/releases\n[license]: https://github.com/phpcfdi/image-captcha-resolver/blob/main/LICENSE\n[build]: https://github.com/phpcfdi/image-captcha-resolver/actions/workflows/build.yml?query=branch:main\n[reliability]:https://sonarcloud.io/component_measures?id=phpcfdi_image-captcha-resolver\u0026metric=Reliability\n[maintainability]: https://sonarcloud.io/component_measures?id=phpcfdi_image-captcha-resolver\u0026metric=Maintainability\n[coverage]: https://sonarcloud.io/component_measures?id=phpcfdi_image-captcha-resolver\u0026metric=Coverage\n[violations]: https://sonarcloud.io/project/issues?id=phpcfdi_image-captcha-resolver\u0026resolved=false\n[downloads]: https://packagist.org/packages/phpcfdi/image-captcha-resolver\n\n[badge-source]: https://img.shields.io/badge/source-phpcfdi/image--captcha--resolver-blue?logo=github\n[badge-discord]: https://img.shields.io/discord/459860554090283019?logo=discord\n[badge-php-version]: https://img.shields.io/packagist/php-v/phpcfdi/image-captcha-resolver?logo=php\n[badge-release]: https://img.shields.io/github/release/phpcfdi/image-captcha-resolver?logo=git\n[badge-license]: https://img.shields.io/github/license/phpcfdi/image-captcha-resolver?logo=open-source-initiative\n[badge-build]: https://img.shields.io/github/actions/workflow/status/phpcfdi/image-captcha-resolver/build.yml?branch=main\u0026logo=github-actions\n[badge-reliability]: https://sonarcloud.io/api/project_badges/measure?project=phpcfdi_image-captcha-resolver\u0026metric=reliability_rating\n[badge-maintainability]: https://sonarcloud.io/api/project_badges/measure?project=phpcfdi_image-captcha-resolver\u0026metric=sqale_rating\n[badge-coverage]: https://img.shields.io/sonar/coverage/phpcfdi_image-captcha-resolver/main?logo=sonarqubecloud\u0026server=https%3A%2F%2Fsonarcloud.io\n[badge-violations]: https://img.shields.io/sonar/violations/phpcfdi_image-captcha-resolver/main?format=long\u0026logo=sonarqubecloud\u0026server=https%3A%2F%2Fsonarcloud.io\n[badge-downloads]: https://img.shields.io/packagist/dt/phpcfdi/image-captcha-resolver?logo=packagist\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpcfdi%2Fimage-captcha-resolver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphpcfdi%2Fimage-captcha-resolver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpcfdi%2Fimage-captcha-resolver/lists"}