-
Notifications
You must be signed in to change notification settings - Fork 2
feat(core): Add watermark 实现 #2122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Close: #1927 Signed-off-by: unknowIfGuestInDream <liang.tang.cx@gmail.com>
Thank you for following naming conventions! 😻 |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Reviewer's GuideThis pull request introduces an image watermarking feature using the Least Significant Bit (LSB) technique. It adds a new File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Their most recently public accepted PR is: #2118 |
Walkthrough本次变更新增了一个基于最不重要位(LSB)的图片隐形水印功能,包括水印的嵌入与提取。核心实现为新建的 Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant LSBWatermark
participant ImageFile
User->>LSBWatermark: addTextWatermark(inputImage, outputImage, watermarkText)
LSBWatermark->>ImageFile: 读取 inputImage
LSBWatermark->>LSBWatermark: 编码 watermarkText 为 bit 序列
LSBWatermark->>ImageFile: 修改像素LSB嵌入水印
LSBWatermark->>ImageFile: 写入 outputImage
User->>LSBWatermark: extractTextWatermark(watermarkedImage)
LSBWatermark->>ImageFile: 读取 watermarkedImage
LSBWatermark->>LSBWatermark: 提取LSB重构水印文本
LSBWatermark-->>User: 返回水印文本
Assessment against linked issues
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @unknowIfGuestInDream - I've reviewed your changes - here's some feedback:
- Consider updating the PR title to use consistent language (e.g., English only).
- Please fill out the 'Proposed Changes' section in the description to summarize the key modifications.
Here's what I looked at during the review
- 🟡 General issues: 2 issues found
- 🟢 Security: all looks good
- 🟡 Testing: 3 issues found
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
core/src/test/java/com/tlcsdm/core/watermark/InvisibleWatermarkTest.java
Show resolved
Hide resolved
core/src/test/java/com/tlcsdm/core/watermark/InvisibleWatermarkTest.java
Show resolved
Hide resolved
core/src/test/java/com/tlcsdm/core/watermark/InvisibleWatermarkTest.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (8)
core/src/main/java/com/tlcsdm/core/watermark/LSBWatermark.java (6)
37-48
: 类文档完善建议类文档说明了LSB水印的局限性,但建议进一步完善:
- 增加对嵌入容量的说明(每个像素可存储3位,即RGB各1位)
- 明确指出只支持PNG格式的原因(JPEG有损压缩会破坏LSB信息)
- 建议添加对使用场景的具体示例
67-68
: 计算公式说明不足计算所需像素数的公式
(watermarkBytes.length * 8 + 2) / 3
中的+ 2
部分目的不明确。建议添加注释说明此计算逻辑,或者修改为更清晰的表达方式。
78-82
: 水印长度限制应在文档中说明当前实现使用16位存储水印长度,这意味着水印最大只能是2^16字节。建议在方法文档中明确说明此限制,以便用户了解适用范围。
150-158
: 字节数组长度校正逻辑可优化当前代码分别处理两种情况:字节数组长度小于或大于预期长度。可以简化为单一的条件判断,提高代码可读性。
// 确保字节数组长度正确 -if (watermarkBytes.length < watermarkLength) { - byte[] correctedBytes = new byte[watermarkLength]; - System.arraycopy(watermarkBytes, 0, correctedBytes, 0, watermarkBytes.length); - watermarkBytes = correctedBytes; -} else if (watermarkBytes.length > watermarkLength) { - byte[] correctedBytes = new byte[watermarkLength]; - System.arraycopy(watermarkBytes, 0, correctedBytes, 0, watermarkLength); - watermarkBytes = correctedBytes; +if (watermarkBytes.length != watermarkLength) { + byte[] correctedBytes = new byte[watermarkLength]; + System.arraycopy(watermarkBytes, 0, correctedBytes, 0, Math.min(watermarkBytes.length, watermarkLength)); + watermarkBytes = correctedBytes; }
171-176
: switch语句中的default分支冗余由于channel变量被限制为0-2(通过
channel = bitIndex % 3
),所以switch语句中的default分支永远不会被执行。建议移除此冗余分支。// 根据位索引决定读取哪个通道的最低有效位 int channel = bitIndex % 3; return switch (channel) { case 0 -> ((rgb >> 16) & 0x01) == 1; case 1 -> ((rgb >> 8) & 0x01) == 1; case 2 -> (rgb & 0x01) == 1; - default -> false; };
49-178
: 建议添加额外的安全措施和功能增强当前实现是LSB水印的基础版本,建议考虑以下增强:
- 添加加密选项,提高水印安全性
- 实现水印扩散机制,使水印更均匀分布在图像中,增加鲁棒性
- 提供检测水印是否存在的方法,而不仅仅是提取水印
- 增加对图像处理操作(如轻微裁剪、旋转)的抵抗能力
此外,建议将静态方法重构为实例方法,提供更灵活的配置选项。
core/src/test/java/com/tlcsdm/core/watermark/InvisibleWatermarkTest.java (2)
43-68
: 建议增加更多的测试场景当前测试只覆盖了基本功能,建议增加以下测试场景:
- 测试图像过小无法容纳水印的情况
- 测试不同长度的水印文本
- 测试水印提取失败的边界情况
- 测试图像处理操作(如剪裁、调整大小)后水印的可提取性
- 测试性能边界(大图像、长水印)
54-54
: 测试数据可配置化水印文本直接硬编码在测试方法中。建议将其抽取为常量或通过参数化方式提供,以便更灵活地测试不同长度和内容的水印。
@ParameterizedTest @ValueSource(strings = {"watermark/originBig.jpg", "watermark/originSmall.png"}) void lsb(String inputImagePath) throws IOException { + // 定义为常量或考虑通过参数化方式提供不同长度的水印文本 + final String WATERMARK_TEXT = "Copyright 2025 - Tlcsdm"; File inputImage = new File(ResourceUtil.getResource(inputImagePath).getFile()); File parentFile = inputImage.getParentFile(); // 添加暗水印 File watermarkedImage = new File(parentFile, FilenameUtils.getBaseName(inputImage.getName()) + "_lsb." + FilenameUtils.getExtension( inputImage.getName())); - String watermarkText = "Copyright 2025 - Tlcsdm"; - LSBWatermark.addTextWatermark(inputImage, watermarkedImage, watermarkText); + LSBWatermark.addTextWatermark(inputImage, watermarkedImage, WATERMARK_TEXT); StaticLog.info("暗水印添加成功!"); // 提取暗水印 String extractedWatermark = LSBWatermark.extractTextWatermark(watermarkedImage); if ("png".equals(FilenameUtils.getExtension(inputImage.getName()))) { - Assertions.assertEquals(watermarkText, extractedWatermark); + Assertions.assertEquals(WATERMARK_TEXT, extractedWatermark); } else { - Assertions.assertNotEquals(watermarkText, extractedWatermark); + Assertions.assertNotEquals(WATERMARK_TEXT, extractedWatermark); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
core/src/test/resources/watermark/originBig.jpg
is excluded by!**/*.jpg
core/src/test/resources/watermark/originSmall.png
is excluded by!**/*.png
📒 Files selected for processing (2)
core/src/main/java/com/tlcsdm/core/watermark/LSBWatermark.java
(1 hunks)core/src/test/java/com/tlcsdm/core/watermark/InvisibleWatermarkTest.java
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
core/src/test/java/com/tlcsdm/core/watermark/InvisibleWatermarkTest.java (1)
core/src/main/java/com/tlcsdm/core/watermark/LSBWatermark.java (1)
LSBWatermark
(49-178)
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: automerge
- GitHub Check: qodana
- GitHub Check: build (21, macos-latest, false)
- GitHub Check: build (21, windows-latest, false)
- GitHub Check: build (17, windows-latest, false)
- GitHub Check: build (21, ubuntu-latest, false)
- GitHub Check: build (17, macos-latest, false)
- GitHub Check: build (17, ubuntu-latest, false)
- GitHub Check: StepSecurity Harden-Runner
- GitHub Check: Summary
🔇 Additional comments (3)
core/src/main/java/com/tlcsdm/core/watermark/LSBWatermark.java (1)
107-111
: 使用了Java 14+的语法特性此处使用了Java 14+引入的switch表达式箭头语法。确保项目的Java版本兼容性要求支持此特性。
core/src/test/java/com/tlcsdm/core/watermark/InvisibleWatermarkTest.java (2)
45-47
: 参数化测试用例命名明确参数化测试使用
@ValueSource
提供了不同格式的图片文件进行测试,设计合理。测试数据包含了JPEG和PNG格式,有效验证了不同格式的支持情况。
61-65
: 测试断言逻辑清晰明确测试断言逻辑正确区分了PNG和其他格式的期望结果:PNG格式应能正确提取水印,而其他格式(如JPEG)则无法正确提取。这符合LSB水印的技术特性和类文档中的说明。
core/src/test/java/com/tlcsdm/core/watermark/InvisibleWatermarkTest.java
Show resolved
Hide resolved
Qodana Community for JVMIt seems all right 👌 No new problems were found according to the checks applied 💡 Qodana analysis was run in the pull request mode: only the changed files were checked Contact Qodana teamContact us at qodana-support@jetbrains.com
|
Close: #1927
Fixes #
Proposed Changes
Readiness Checklist
Author/Contributor
Reviewing Maintainer
enhancement
,bug
,documentation
ordependencies
Summary by Sourcery
Implement a Least Significant Bit (LSB) watermarking technique for images, allowing embedding and extraction of invisible text watermarks
New Features:
Tests:
Chores:
Summary by CodeRabbit