{"id":31544577,"url":"https://github.com/pngencoder/pngencoder","last_synced_at":"2025-10-04T13:48:41.334Z","repository":{"id":40481293,"uuid":"288132773","full_name":"pngencoder/pngencoder","owner":"pngencoder","description":"A really fast encoder for PNG images in Java.","archived":false,"fork":false,"pushed_at":"2025-10-03T09:23:33.000Z","size":28126,"stargazers_count":43,"open_issues_count":2,"forks_count":7,"subscribers_count":5,"default_branch":"develop","last_synced_at":"2025-10-03T11:34:57.759Z","etag":null,"topics":["imageio","java","java-8","java-library","java8","png","png-compression","png-compressor","png-encoder"],"latest_commit_sha":null,"homepage":"","language":"Java","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/pngencoder.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":null,"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":"2020-08-17T09:04:51.000Z","updated_at":"2025-10-03T09:23:35.000Z","dependencies_parsed_at":"2023-02-09T02:16:22.260Z","dependency_job_id":"affec461-6b44-4b3d-887e-4d1c9813d071","html_url":"https://github.com/pngencoder/pngencoder","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/pngencoder/pngencoder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pngencoder%2Fpngencoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pngencoder%2Fpngencoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pngencoder%2Fpngencoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pngencoder%2Fpngencoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pngencoder","download_url":"https://codeload.github.com/pngencoder/pngencoder/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pngencoder%2Fpngencoder/sbom","scorecard":{"id":553158,"data":{"date":"2025-08-11","repo":{"name":"github.com/pngencoder/pngencoder","commit":"337574d85aca8fbdae29f3745dd505d5c63a0e96"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/maven.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/10 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Info: Possibly incomplete results: error parsing job operating system: .github/workflows/maven.yml:36","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/pngencoder/pngencoder/maven.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/maven.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/pngencoder/pngencoder/maven.yml/develop?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":10,"reason":"12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T11:30:43.693Z","repository_id":40481293,"created_at":"2025-08-20T11:30:43.693Z","updated_at":"2025-08-20T11:30:43.693Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278173367,"owners_count":25942293,"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","status":"online","status_checked_at":"2025-10-03T02:00:06.070Z","response_time":53,"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":["imageio","java","java-8","java-library","java8","png","png-compression","png-compressor","png-encoder"],"created_at":"2025-10-04T13:48:38.450Z","updated_at":"2025-10-04T13:48:41.329Z","avatar_url":"https://github.com/pngencoder.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"![PngEncoder Logo](https://user-images.githubusercontent.com/421009/85217670-be26ce00-b393-11ea-8741-4da520fc2dd2.png)\n\n\n\u003cimg src=\"https://img.shields.io/maven-central/v/com.pngencoder/pngencoder\"\u003e \u003cimg src=\"https://img.shields.io/codecov/c/github/pngencoder/pngencoder/develop?token=305f39ec177948b3bde322c021debcdf\"\u003e\n\n- About 5 times faster than ImageIO (on a computer with 8 logical cores)\n- Optional with better compression than ImageIO at the cost of speed by using predictor encoding.\n- Support for 8-bit and 16-bit RGB, ARGB, grayscale and indexed images.\n- ICC color profiles are exported when needed\n- Easy to use interface\n- [Semantic Versioning](http://semver.org/)\n- [MIT License](LICENSE)\n- Java 8\n\n## Examples\n\n```java\nimport com.pngencoder.PngEncoder;\nimport com.pngencoder.PngEncoderBufferedImageConverter;\n\npublic class Examples {\n    public static void encodeToOutputStream(BufferedImage bufferedImage, OutputStream outputStream) {\n        new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .toStream(outputStream);\n    }\n\n    public static void encodeToFile(BufferedImage bufferedImage, File file) {\n        new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .toFile(file);\n    }\n\n    public static void encodeToFilePath(BufferedImage bufferedImage, Path filePath) {\n        new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .toFile(filePath);\n    }\n\n    public static void encodeToFileName(BufferedImage bufferedImage, String fileName) {\n        new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .toFile(fileName);\n    }\n\n    public static byte[] encodeToBytes(BufferedImage bufferedImage) {\n        return new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .toBytes();\n    }\n\n    public static byte[] encodeWithBestPredictorCompression(BufferedImage bufferedImage) {\n        // This produces image files way smaller than what ImageIO does. But\n        // it takes also way more time. Predictor encoding is off by default as it\n        // causes a performance hit.\n        return new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .withPredictorEncoding(true)\n                .withCompressionLevel(9)\n                .toBytes();\n    }\n\n    public static byte[] encodeWithBestCompressionWithoutPredictor(BufferedImage bufferedImage) {\n        // Compression level 9 is the default, and you actually need not set it.\n        // It produces images with a size comparable to ImageIO.\n        return new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .withCompressionLevel(9)\n                .toBytes();\n    }\n\n    public static byte[] encodeWithBestSpeed(BufferedImage bufferedImage) {\n        // If speed is more important than size you can lower the compression level.\n        // 1 is about three times faster but the file becomes about three times larger.\n        return new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .withCompressionLevel(1)\n                .toBytes();\n    }\n\n    public static byte[] encodeWithBestCompressionTryIndexedEncoding(BufferedImage bufferedImage) {\n        // If there are likely no more than 256 colors used in the image (including color+alpha combinations),\n        // then you can try the indexed encoding. If it does not work, as there are more than 256 colors, it \n        // will silently fall back to normal encoding. This setting will give you the best possible compression,\n        // but may also take the most time. \n        return new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .withCompressionLevel(9)\n                .withTryIndexedEncoding(true)\n                .withPredictorEncoding(true)\n                .toBytes();\n    }\n\n    public static CompletableFuture\u003cVoid\u003e encodeToFileInOtherThread(BufferedImage bufferedImage, File file) {\n        // Perhaps all the work can be done async to let the main thread continue?\n        // More of a general performance tip that's not limited to this PngEncoder library.\n        return CompletableFuture.runAsync(() -\u003e new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .toFile(file));\n    }\n\n    public static byte[] encodeIntArgbData(int[] data, int width, int height) {\n        // Creating the BufferedImage this way is almost instant.\n        // It uses the underlying int[] data directly.\n        BufferedImage bufferedImage = PngEncoderBufferedImageConverter.createFromIntArgb(data, width, height);\n        return new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .toBytes();\n    }\n\n    public static byte[] encodeWithMultiThreadedCompressionDisabled(BufferedImage bufferedImage) {\n        // By default, the compression is done in multiple threads.\n        // This improves the speed a lot, but you can disable it to compress in the invoking thread only.\n        return new PngEncoder()\n                .withBufferedImage(bufferedImage)\n                .withMultiThreadedCompressionDisabled()\n                .toBytes();\n    }\n}\n```\n\n## Maven Central\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.pngencoder\u003c/groupId\u003e\n    \u003cartifactId\u003epngencoder\u003c/artifactId\u003e\n    \u003cversion\u003e0.16.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nhttps://search.maven.org/artifact/com.pngencoder/pngencoder\n\n## PngEncoder vs ImageIO\nThe table below shows the number of images encoded per second, using PngEncoder vs ImageIO:\nImage | PngEncoder | ImageIO | Times Faster\n--- | --- | --- | ---\nrandom1024x1024 | 36.324 | 5.150 | 7.1\nlogo2121x350 | 127.034 | 24.857 | 5.1\nlooklet4900x6000 | 0.159 | 0.029 | 5.5\n\nRun yourself using [PngEncoderBenchmarkPngEncoderVsImageIO.java](src/test/java/com/pngencoder/PngEncoderBenchmarkPngEncoderVsImageIO.java)\n\nNote that these numbers are for the default compression level 9 which produces images of about the same size as ImageIO. By lowering the compression level we can speed up encoding further. See the table below. \nAll this is without the predictor encoding.\n\n## Compression Speed vs Size\n\n| Compression Level | Speed | Size   | Speed / Size |\n|-------------------|-------|--------|--------------|\n| 9 (default)       | 1.00  | 1.00   | 1.00         |\n| 8                 | 1.10  | 1.14   | 0.97         |\n| 7                 | 1.36  | 1.24   | 1.10         |\n| 6                 | 1.40  | 1.23   | 1.14         |\n| 5                 | 1.46  | 1.29   | 1.13         |\n| 4                 | 1.49  | 1.30   | 1.15         |\n| 3                 | 2.33  | 2.30   | 1.02         |\n| 2                 | 2.31  | 2.42   | 0.96         |\n| 1                 | 2.31  | 2.50   | 0.92         |\n| 0                 | 3.11  | 206.80 | 0.02         |\n\nRun yourself using [PngEncoderBenchmarkCompressionSpeedVsSize.java](src/test/java/com/pngencoder/PngEncoderBenchmarkCompressionSpeedVsSize.java)\n\nIn the table above we see that the \"Speed / Size\" column is close to 1 for all compression levels but 0. You likely want to avoid compression level 0 (no compression) if the file size matters at all. In comparison to using compression level 1 it's 35% faster, but the file size is a whopping 827%. That is likely not worth it.\n\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md)\n\n\n## Noteworthy Caveats\nThis library achieves the speedup mainly using multithreading. The performance tests above were run on a computer with 8 logical cores. So if you for example use a single core computer (perhaps in the cloud) the speedup will not be significant.\n\nWhen using multithreading without predictor encoding the file size is about 2% larger than images encoded by ImageIO. This small overhead is due to the multithreaded compression.\n\nSupport for metadata is currently close to zero. If you need comments in your PNG file this library does not support that at the moment.\n\n## Contributing\nWhen contributing please respect the style guide in the [CONTRIBUTING.md](./CONTRIBUTING.md). If you use IntellJ IDEA you can import the  [looklet_intellij_code_style.xml](./looklet_intellij_code_style.xml)\nto have IDEA setup with the right settings. \n\n## Looklet\nWe develop and use this library at https://www.looklet.com/ to quickly compress high quality fashion images for e-commerce.\n\nAre you a skilled Java or React developer? Feel free to join in: https://www.looklet.com/career/job-openings/\n\n\u003cimg src=\"https://user-images.githubusercontent.com/421009/90376713-2e418f80-e077-11ea-8018-9c79ecf9d519.jpg\" width=\"200\" alt=\"Looklet Fashion Image\"/\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpngencoder%2Fpngencoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpngencoder%2Fpngencoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpngencoder%2Fpngencoder/lists"}