【Java編程】【計算機視覺】一種簡單的圖片加/解密算法

by Li y.c.

一、內容簡介

本文介紹一種簡單的圖片加/解密算法,算法的基本原理十分簡單,即逐個(逐行、逐列)地獲取圖片的像素點顏色值,對其進行一些簡單的算數運算操作進行加密,解密過程則相應地為加密運算的逆運算。

二、圖片表示基礎

在計算機中,圖片(我們使用.jpg文件作為示例)在內存中是使用RGB數組進行存儲,舉例:

在這里插入圖片描述

以上圖片中,每一個像素點用一個rgb值表示,一般為6位16進制數,例如0x123456,這里0x12表示紅度(RED)值,0x34表示綠度(GREEN)值,0x56表示藍度(BLUE)值。注意到,兩位16進制數的取值范圍為0~255(0x00到0xFF)。

三、R/G/B值的獲取

假如我們知道當前像素點的rgb值為0x123456,如何從中獲取到分離的r/g/b值呢?通過簡單的位運算即可。如以下java代碼:

public class RGBTest {public static void main(String[] args) {String format1 = String.format("%x", (0x123456 >> 16));  // 獲取red值(前兩位)String format2 = String.format("%x", (0x123456 >> 8) & 0xFF);  // 獲取green值(中間兩位)String format3 = String.format("%x", (0x123456) & 0xFF);  // 獲取blue值(末兩位)String format = String.format("%x", (0x123456) & 0xFFFFFF);  // 不做改變System.out.println(format1);System.out.println(format2);System.out.println(format3);System.out.println(format);}
}

運行結果正是我們想要的:

在這里插入圖片描述

四、獲取整張圖片的RGB數組

有了以上的基礎,我們就可以將整張圖片存儲為一個RGB表示的數組,為之后的加/解密操作做基礎。使用如下的Java代碼:

public List<Integer> getRGB(BufferedImage image, int x, int y) {List<Integer> rgb = new ArrayList<Integer>();if (image != null && x <= image.getWidth() && y <= image.getHeight()) {for (int h = 0; h < y; h++) {for (int w = 0; w < x; w++) {//獲得w,h坐標的顏色int pixel = image.getRGB(w, h);rgb.add(pixel);}}}return rgb;}

五、加密函數

我們使用簡單的加密操作,即把圖片的R/G/B值同時加50后模256(防止值溢出造成噪點【可以想見,若某一通道出現進位,后果是災難性的】):

// 加密函數public static void Encrypt(Integer[] rgb, int width, int height) {// 輸出文件名File file = new File("image_out.jpg");BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics2D g2 = (Graphics2D) bi.getGraphics();for (int h = 0; h < height; h++) {for (int w = 0; w < width; w++) {int color = rgb[w + width * h];int red = color >> 16;int green = (color >> 8) & 0xFF;int blue = color & 0xFF;int red_ = (red + 50) % 256;int green_ = (green + 50) % 256;int blue_ = (blue + 50) % 256;Color c = new Color(red_ << 16 | green_ << 8 | blue_);g2.setColor(c);g2.drawLine(w, h, w + 1, h + 1);}}try {ImageIO.write(bi, "jpg", file);} catch (IOException e) {e.printStackTrace();}}

看看加密效果:(以下代碼位于主函數中)

// 加密部分:【image_1_1.jpg】---【image_out.jpg】Image_Encrypt r = new Image_Encrypt();File f = new File("image_1_1.jpg");BufferedImage bi = ImageIO.read(f);int width = bi.getWidth();int height = bi.getHeight();List<Integer> l = null;Integer[] rbg = new Integer[width * height];l = r.getRGB(bi, width, height);
//             查看rgb值:
//            System.out.print(l);for (int i = 0; i < width * height; i++) {rbg[i] = l.get(i);}Encrypt(rbg, width, height);

加密后的圖像:

在這里插入圖片描述

六、解密函數

解密函數應為加密函數的逆運算,考慮到邊緣條件,代碼如下:

// 解密函數public static void Decrypt(Integer[] rgb, int width, int height) {// 輸出文件名File file = new File("image_out_de.jpg");BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics2D g2 = (Graphics2D) bi.getGraphics();for (int h = 0; h < height; h++) {for (int w = 0; w < width; w++) {int color = rgb[w + width * h];int red = color >> 16;int green = (color >> 8) & 0xFF;int blue = color & 0xFF;int red_;if (red == 255){red_ = 255;}else{red_ = (red - 50 + 255) % 255;}int green_;if (green == 255){green_ = 255;}else{green_ = (green - 50 + 255) % 255;}int blue_;if (blue == 255){blue_ = 255;}else{blue_ = (blue - 50 + 255) % 255;}Color c = new Color(red_ << 16 | green_ << 8 | blue_);g2.setColor(c);g2.drawLine(w, h, w + 1, h + 1);}}try {ImageIO.write(bi, "jpg", file);} catch (IOException e) {e.printStackTrace();}}

解密后的圖像卻是這樣的:

在這里插入圖片描述

推測是由于邊緣條件造成的,修改代碼中……

【debug】
我們寫一個測試類,看看從0到255的值里面,是否有不滿足該逆運算關系的:

public class Test {public static void main(String[] args){for (int i = 0;i <= 255;i ++){int j = (i + 50) % 256;int j_ = (j - 50 + 256) % 256;if (i != j_){System.out.print("errr");}}}
}

輸出如下:

【沒有報錯】……??

基準測試

加/解密均不做任何操作,直接由三通道的值拼湊出rgb數組:

加密函數

// 加密函數public static void Encrypt(Integer[] rgb, int width, int height) {// 輸出文件名File file = new File("image_out.jpg");BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics2D g2 = (Graphics2D) bi.getGraphics();for (int h = 0; h < height; h++) {for (int w = 0; w < width; w++) {int color = rgb[w + width * h];int red = color >> 16;int green = (color >> 8) & 0xFF;int blue = color & 0xFF;// 基準測試int red_ = red;int green_ = green;int blue_ = blue;//                int red_ = (red + 50) % 256;
//                int green_ = (green + 50) % 256;
//                int blue_ = (blue + 50) % 256;Color c = new Color(red_ << 16 | green_ << 8 | blue_);g2.setColor(c);g2.drawLine(w, h, w + 1, h + 1);}}try {ImageIO.write(bi, "jpg", file);} catch (IOException e) {e.printStackTrace();}}

解密函數

// 解密函數public static void Decrypt(Integer[] rgb, int width, int height) {// 輸出文件名File file = new File("image_out_de.jpg");BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics2D g2 = (Graphics2D) bi.getGraphics();for (int h = 0; h < height; h++) {for (int w = 0; w < width; w++) {int color = rgb[w + width * h];int red = color >> 16;int green = (color >> 8) & 0xFF;int blue = color & 0xFF;// 基準測試int red_ = red;int green_ = green;int blue_ = blue;
//                int red_;
//                if (red == 255){
//                    red_ = 255;
//                }
//                else{
//                    red_ = (red - 50 + 256) % 256;
//                }//                int green_;
//                if (green == 255){
//                    green_ = 255;
//                }
//                else{
//                    green_ = (green - 50 + 256) % 256;
//                }//                int blue_;
//                if (blue == 255){
//                    blue_ = 255;
//                }
//                else{
//                    blue_ = (blue - 50 + 256) % 256;
//                }Color c = new Color(red_ << 16 | green_ << 8 | blue_);g2.setColor(c);g2.drawLine(w, h, w + 1, h + 1);}}try {ImageIO.write(bi, "jpg", file);} catch (IOException e) {e.printStackTrace();}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/79362.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79362.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/79362.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從GPT到Gemini 大模型進化史

從GPT到Gemini&#xff1a;大模型進化史 在過去的幾年里&#xff0c;人工智能領域經歷了翻天覆地的變化&#xff0c;其中最引人注目的莫過于大規模語言模型的發展。從最初的GPT系列到最近的Gemini&#xff0c;這些模型不僅在技術上取得了重大突破&#xff0c;還在實際應用中展…

【AI提示詞】中國歷史與世界發展對比器

提示說明 輸入特定年份&#xff0c;輸出該時期中國與世界的發展狀況。 提示詞 # Role 中國歷史與世界發展對比器## Profile - author: xxx - version: 1.0 - description: 輸入特定年份&#xff0c;輸出該時期中國與世界的發展狀況。## Attention 請深入挖掘歷史資料&#x…

阿里云OSS應對DDoS攻擊策略

阿里云對象存儲服務&#xff08;OSS&#xff09;若遭遇DDoS攻擊&#xff0c;可結合阿里云提供的安全服務與自身配置優化進行綜合防御。以下是具體的解決方案及步驟&#xff1a; 1. 啟用阿里云DDoS防護服務 防護服務類型&#xff1a;阿里云提供基礎DDoS防護&#xff08;默認免費…

MyCat 分庫分表

介紹 問題分析 隨著互聯網及移動互聯網的發展&#xff0c;應用系統的數據量也是成指數式增長&#xff0c;若采用單數據庫進行數據存 儲&#xff0c;存在以下性能瓶頸&#xff1a; 1. IO瓶頸&#xff1a;熱點數據太多&#xff0c;數據庫緩存不足&#xff0c;產生大量磁盤IO&a…

C++筆記-list

list即是我們之前學的鏈表&#xff0c;這篇主要還是講解list的底層實現&#xff0c;前面會講一些list區別于前面string和vector的一些接口以及它們的注意事項。 一.list的基本使用 和之前的string&#xff0c;vector一樣&#xff0c;有很多之前見過的一些接口&#xff0c;經過…

unityTEngine學習記錄2

上一篇了解了下載項目與外部調用的接口&#xff0c;接下來就繼續學習根據這個框架來加載場景首先打開te官網&#xff0c;進入教程。 了解框架目錄以及功能 首先要了解的就是這個框架的文件結構目錄&#xff0c;知道他都是干啥的&#xff0c;在官網的目錄結構中介紹了其中重要…

邏輯過期怎么設計

設計“邏輯過期”通常用于緩存、令牌管理、數據有效性驗證等場景&#xff0c;其核心是通過業務邏輯判斷數據是否過期&#xff08;而非單純依賴物理時間&#xff09;。以下是設計邏輯過期的關鍵思路和實現方案&#xff1a; 1. 核心思想 物理過期&#xff1a;基于固定的時間&…

DAY 47 leetcode 232--棧與隊列.用棧實現隊列

題號232 請你僅使用兩個棧實現先入先出隊列。隊列應當支持一般隊列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; class MyQueue {Stack<Integer> stackIn;Stack<Integer> stackOut;/** Initialize your data structure here. */pu…

邏輯回歸 (Logistic Regression)

文章目錄 邏輯回歸 (Logistic Regression)問題的引出Sigmoid function邏輯回歸的解釋決策邊界 (Decision boundary)邏輯回歸的代價函數機器學習中代價函數的設計1. 代價函數的來源&#xff08;1&#xff09;從概率模型推導而來&#xff08;統計學習視角&#xff09;&#xff08…

關于C語言的模擬物理模型

聲明&#xff1a;本文全部代碼效果基于C語言easyx圖形界面庫。 引言 關于很多游戲和模型的開發&#xff0c;都需要模擬真實的物理模型 比如&#xff1a;基本矢量運動模型&#xff08;位移&#xff0c;速度&#xff0c;加速度&#xff09;&#xff0c;重力模型&#xff0c;碰撞…

C++編譯與鏈接:從源碼到可執行文件的魔法之旅(Visual Studio實踐)

文章目錄 **C++編譯與鏈接:從源碼到可執行文件的魔法之旅(Visual Studio實踐)****一、C++編譯器的工作流程****二、Visual Studio環境配置實戰****三、示例項目:Hello World全流程解析****四、高級技巧與工具鏈****五、總結與參考資料**C++編譯與鏈接:從源碼到可執行文件的…

現代C++的范式演進與工程實踐深度解析(本文序號不知道怎么整的,有點問題)

引言:C++的復興時代 在經歷了"已死語言"的質疑后,現代C++正迎來前所未有的復興。據2024年TIOBE指數顯示,C++以8.33%的占比穩居第三,較2020年上升2.1個百分點。這種復興并非偶然——隨著C++20標準的全面落地和C++23特性的逐步實現,這門已有40年歷史的語言正在系…

通過gird布局實現div的響應式分布排列

目標&#xff1a;實現對于固定寬度的div盒子在頁面中自適應排布&#xff0c;并且最后一行的div盒子可以與前面的盒子對齊。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" con…

WSL2-Ubuntu22.04安裝URSim5.21.3

WSL2-Ubuntu22.04安裝URSim5.21.3 準備安裝啟動 準備 名稱版本WSL2Ubuntu22.04URSim5.21.3VcXsrvNaN WSL2安裝與可視化請見這篇:WSL2-Ubuntu22.04-配置。 安裝 我們是wsl2-ubuntu22.04&#xff0c;所以安裝Linux版本的URSim&#xff0c;下載之前需要注冊一下&#xff0c;即…

產品研發項目管理6大痛點

在產品研發項目管理實踐中&#xff0c;企業普遍面臨六大系統性挑戰&#x1f937;?♀?&#xff0c;直接影響研發效能與戰略目標達成&#x1f514;&#xff0c;具體表現為&#xff1a; ① 產品需求管理不完善&#xff1a;需求與市場脫節&#xff0c;需求不明確、需求變更頻繁…

計算機網絡基礎概論

計算機網絡基礎概論 目錄 一、網絡基本概念 1.1. 網絡 1.2 互聯網 1.3 ip地址 1.3.1 作用 1.3.2 分類 1.4 MAC地址 1.4.1 MAC地址與 IP 地址的關系 1.5 網絡協議 二、網絡分層模型 2.1 物理層 2.2 數據鏈路層 2.3 網絡層 2.4 傳輸層 2.5 會話層 2.6 表示層 2.7…

Windows下導入文件中的環境變量

在Windows批處理腳本&#xff08;.bat&#xff09;中&#xff0c;通過文件獲取并設置環境變量通常涉及逐行讀取文件內容并動態賦值給變量。以下是具體實現方法及示例&#xff1a; 一、從文件讀取變量并設置到環境變量 假設有一個配置文件&#xff08;如env_config.txt&#xf…

WebSocket 實現數據實時推送原理

WebSocket 實現數據實時推送的核心機制在于其全雙工通信能力和持久的連接特性。以下是其工作原理的詳細步驟&#xff1a; 1. 握手階段&#xff08;HTTP 升級協議&#xff09; 客戶端發起請求&#xff1a;通過發送一個帶有特殊頭部的 HTTP 請求&#xff0c;請求協議升級。 GET …

Linux操作系統學習之---進程狀態

目錄 明確進程的概念: Linux下的進程狀態: 虛擬終端的概念: 見一見現象: 用途之一 : 結合指令來監控進程的狀態: 和進程強相關的系統調用函數接口: getpid()和getppid(): fork(): fork函數創建子進程的分流邏輯: 進程之間具有獨立性: 進程中存在的寫時拷貝: 見一見進程狀態…

何小鵬在得意的笑

"小鵬汽車率先邁出了造車新勢力出海一大步" 作者 | 魏強 編輯 | 盧旭成 4月15日&#xff0c;小鵬汽車在香港舉行小鵬全球熱愛之夜和2025首款全球旗艦小鵬X9上市發布會。 當小鵬汽車創始人何小鵬把香車X9交付給香港首批車主的時候&#xff0c;臉上露出經典的笑臉。…