나는 지금 한동안 일해 왔습니다. 처음으로 블로그를 작성하고 있습니다. 글을 쓰는 방법을 모르겠습니다. 그냥 읽자. 잘못된 단어가 있으면 저를 수정 해주세요.
최근에 이미지 압축 기능이 작업에 사용되었습니다. 나는 몇 가지 도구를 찾았지만 좋은 선택은 없었습니다. 마지막으로, 나는 Jdeli라는 사람을 선택했지만 효율성은 다시 문제가되었습니다. 나는 소스 코드를 연구 할 수밖에 없었지만, 차감 양자화 알고리즘 중 하나에 관심이 있다는 것을 알았습니다. 그러나 나는 그것이 무엇을 쓰고 있는지 전혀 이해하지 못한다는 사실에 부끄러 웠기 때문에 혼자서 양적 색상 알고리즘을 구현한다는 아이디어가있었습니다.
나는 몇 가지 정보를 직접 찾았고 세 가지 더 일반적으로 사용되는 색상 처리 알고리즘을 발견했습니다.
인기있는 색상 알고리즘 :
특정 알고리즘은 먼저 모든 색상이 이미지에 나타나는 횟수를 계산하고, 가장 많이 발생하는 256 색상을 그림 팔레트의 색상으로 선택한 다음 그림의 모든 픽셀을 다시 반복하고, 각 픽셀의 팔레트에서 가장 가까운 색상을 찾아서 그림에 다시 씁니다. 이 알고리즘의 구현은 비교적 간단하지만 왜곡은 비교적 심각합니다. 일부 이미지는 저주파수로 나타나지 만 인간의 눈에 시각적 효과는 분명합니다. 정보가 손실됩니다. 예를 들어, 이미지의 높은 엽면 지점은 적은 수의 발생으로 인해 알고리즘에 의해 선택되지 않을 수 있으며 손실됩니다.
중간 슬라이싱 알고리즘 :
이 알고리즘을 연구하지 않았습니다. 알고 싶은 사람들은이 기사를 읽을 수 있으며, 여기에는 세 가지 알고리즘의 소개가 포함되어 있습니다.
옥타브 트리
이 알고리즘은 내가 선택한 마지막 알고리즘입니다. 주요 아이디어는 이미지의 RGB 색상 값을 이진 분포로 변환하는 것입니다. 예를 들어 : (173,234,144)
바이너리로 변환하려면 (10101101, 11101010, 10010000), R, G, B의 첫 번째 비트를 꺼내고 (111), 루트 노드의 자식 노드 역할을하며, 여기서 111은 루트 하위 노드 어레이의 색인이며 마지막 비트 까지이 색상의 구성 요소 및 잎사귀의 구성 요소 값을 저장하십시오. 자세한 내용은 사진을 참조하십시오.
내가 더 혼란스러워하는 것 중 하나는 잎 노드의 병합 전략입니다. 내가 여기서 사용하는 가장 어리석은 방법은 가장 깊은 노드를 찾은 다음 병합하는 것입니다. 약간 간단하고 조잡합니다. 다른 더 나은 방법이 있습니다. 메시지를 남겨주세요. 사진이 너무 커서 업로드 할 수 없으므로 코드를 업로드합니다. 코드는 리팩토링되지 않았으므로 모든 사람이 읽을 수 있습니다.
package com.gys.pngquant.octree; import java.util.arraylist; import java.util.hashmap; import java.util.list; import java.util.map;/** * * @classname 클래스 이름 : node * @description function description : * <p> * * * * * * * * 2015-12-16 GUS. *****************************************************************************/p>*/public class node {private int depth = 0; // 0 일 때, 그것은 루트 노드 개인 노드 부모; 개인 노드 [] children = new node [8]; 개인 부울 = 0; 개인 gnum = 0; piexls = 0; private map <integer, list <node >> levelmapping; // 계층 구조와 노드 공개 int getrgbvalue () {int r = this.rnum / this.piexls; int g = this.gnum / this.piexls; int b = this.bnum / this.piexls; b);} public map <integer, list <node >> getLevelMapping () {return levelmapping;} public void afterSetparam () {if (this.getParent () == null && this.depth == 0) {levelmapping = new Hashmap <정수, 목록 <node >> (in in <= 8; i ++); {levelmapping.put (i, new arraylist <node> ());}}} public int getrnum () {return rnum;} public void setrnum (int rnum) {if (! isleaf) {wash insupportedoperationException ();} public getgnum;} public getgnum () {returegnum = rnum;} setgnum (int gnum) {if (! isleaf) {새로운 비 영업 외부 exception ();} this.gnum = gnum;} public int getbnum () {return bnum;} public void setbnum (int bnum) {if (! isleaf)) {wash new new instorperationexception (); getpiexls () {return piexls;} public void setpiexls (int piexls) {if (! isleaf) {throw new unsupportedoperationexception ();} this.piexls = piexls;} public int getdepth () {return depth;} // node int int의 수를 반환합니다. mergerLeafnode () {if (this.isleaf) {return 1;} this.setLeaf (true); int rnum = 0; int gnum = 0; int bnum = 0; int pixel = 0; int i = 0; for (node child : child == null) {child += child. child.getgnum (); bnum += child.getbnum (); pixel += child.getpiexls (); i += 1;} this.setrnum (rnum); this.setgnum (gnum); this.setbnum (bnum); this.setpiexls (pixel); node getDepestNode () {for (int i = 7; i> 0; i-) {list <node> levellist = this.levelmapping.get (i); if (! levellist.isempty ()) {levellist.size ()-1); getLeafnum () {if (isleaf) {return 1;} int i = 0; for (node child : this.children) {if (child! = null) {i += child.getLeafnum ();}} public void setdepth (int 깊이) {this.depth = depphth;) setParent (node parent) {this.parent = parent;} public node [] getchildren () {return children;} public node getchild (int index) {return children [index];} public void setchild (int index, node node) {children [index] = node;} public boolean isleaf (int int gen ger int gen gen geng) b) {this.rnum += r; this.gnum += g; this.bnum += b; this.piexls += 1;} public void setLeaf (boolean isleaf) {this.isleaf = isleaf;} public void add8bite2Root (int _Taget, int _speed) {depth! = 0 | 새로운 UnsupportedOperationException ();} int speed = 7 + 1-_speed; int r = _taget >> 16 & 0xff; int g = _taget >> 8 & 0xff; int b = _taget & 0xff; 노드 pronode = this (int i = 7; i> = 속도; i-) {in item = (r >> <2) <2). I & 1) << 1) + (b >> i & 1); 노드 child = pronode.getchild (item); if (child == null) {child = new node (); child.setdepth (8-i); child.setparent (pronode); child.aftersetparam (); child.levelmapping.get () child);} if (i == 속도) {child.setleaf (true);} if (child.isleaf ()) {child.setpixel (r, g, b); break;} pronode = child;}} public static node build (int [] []] [] matrix, int speed) {node root = new node (); root.ftersetparam (); for (int [] row : matrix) {for (int cell : row) {ut root.getLeafnum (); try {while (leafnum> maxColors) {int mergerleafnode = root.getDepestNode (). MergerLeafnode (); Leafnum - = (MergerLeafNode -1);}} catch (예외 e) {e.printstacktrace ();} fillArray (root, 0); 결과) {bytearray [i ++] = byte1;} return bytearray;} private static void fillArray (Node Node, List <Byte> result, int offset) {if (node == null) {return;} if (node.isleaf ()) {result.add ((byte)) node.getpiexls ())); result.add ((byte) (node.getgnum () / node.getpiexls ()); result.add ((byte) (node.getBnum () / node.getPiexls ())) else {for (node child : node.getChildren ()) {fillArray (child, result, orpset);}}}}대학에서 나의 유일한 데이터 구조가 나쁘다. 코드는 Octree만을 구현합니다. 1920*1080 이미지를 정량화하는 데 약 450ms가 걸리고 레벨 -2 인 경우 약 100ms입니다.
좋아, 그게 다야. 내가 쓰기 전에, 나는 많이 말하고 싶다고 느꼈지만, 글을 쓸 때 무엇을 말 해야할지 몰랐습니다. 저를 용서 해주세요.
요약
위의 내용은 Java의 Octree 이미지 처리 코드 예제에 대한 Java의 간단한 구현에 대한이 기사의 모든 내용입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!