자바 그림 의 녹색 픽 셀 점 에 따라 정렬

머리말
한 친구 가 녹색 이 되 어 녹색 을 보면 슬퍼 집 니 다.좋 은 형제 인 저 는 당연히 못 보 겠 습 니 다.저도 뭔 가 를 해 야 할 것 같 습 니 다.마침 나 는 자바 프로그램 을 쓰 고 있 었 다.그러면 작은 프로그램 을 써 서 컴퓨터 안의 그림 을 순 서 를 정 해 주 고 녹색 정도 에 따라 순 서 를 정 한 다음 에 순 서 를 정 한 그림 을 몰래 그의 컴퓨터 에 넣 어 주 었 다.좋 은 형 제 를 위해 이렇게 많은 일 을 하 는 것 은 바로 일이 있 으 면 옷 을 벗 고 공 은 몸 과 이름 을 숨 기 는 것 이다!역순
1.for 순환 으로 그림 읽 기
이미지 처 리 를 배 운 친구 들 은 한 장의 그림 이 많은 픽 셀 로 구성 되 어 있다 는 것 을 알 고 있다.(물론 벡터 그림 을 제외 하고 왜 벡터 그림 이 픽 셀 로 구성 되 지 않 는 지 알 수 있다.)따라서 어떤 그림 이 든 우 리 는 평면 으로 본다.왜냐하면 좌표 로 그림 을 읽 을 수 있 기 때문이다!그럼 잔말 말고 바로 시작!
2.코드 의 논리
1.메 인 방법 안에 어떤 내용 이 들 어 있 는 지 먼저 보 여 준다.

public static void main(String[] args) {
		HashMap<File, Object> imageMap = new HashMap<File, Object>();// hashMap                
		File fileDir = new File("D:\\Download\\TestFile");//           
		File[] listFiles = fileDir.listFiles();
		for (File readFile : listFiles) {
			getImagePixel(readFile, imageMap);//               
		}
		
		HashMapSortUtils hashMapSortUtils = new HashMapSortUtils(imageMap, 1, 3, "Mus");
		LinkedHashMap<File,Object> sortFileMap = hashMapSortUtils.sortFileMap();//               
		hashMapSortUtils.renameFiles(sortFileMap);//          (                 >o<)
		
		System.out.println(imageMap);//                ,        
	}
쉽 지 않 아 요?코끼리 냉장고 에 넣 는 것 과 마찬가지 로 세 가지 절차 만 있다.
1.파일 디 렉 터 리 에 있 는 모든 그림 에 포 함 된 녹색 픽 셀 점 을 모두 읽 은 다음 해당 하 는 파일 이름과 픽 셀 점 개 수 를 HashMap 에 임시 저장 합 니 다.
2.녹색 픽 셀 의 크기 에 따라 그림 을 정렬 합 니 다.
3.정렬 된 그림 의 이름 을 바 꾸 고 정렬 출력 을 합 니 다(Tips:파일 은 이름 을 바 꿉 니 다.원본 파일 에서 직접 놀 지 마 십시오.파일 백업 에 주의 하 십시오).
자,그럼 모든 방법 이 구체 적 으로 어떻게 실현 되 는 지 순서대로 설명 합 시다!(다음은 코드 에 있 는 주석 을 주의 깊 게 살 펴 보고 중복 해석 을 하지 않 겠 습 니 다)
2.픽 셀 을 읽 는 방법

private static HashMap<File, Object> getImagePixel(File readFile, HashMap<File, Object> imageMap) {
		int red = 0;//        
		int green = 0;//        
		int blue = 0;//        
		int counter = 0;//     
		
		BufferedImage bi = null;
		try {
			bi = ImageIO.read(readFile);//  ImageIO     ,       RGB  
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		int width = bi.getWidth();//       
		int height = bi.getHeight();//       
		int minx = bi.getMinX();//         x 
		int miny = bi.getMinY();//         y 
		
		for(int i = minx; i < width; i++){
			for(int j = miny; j < height; j++){
				int pixel = bi.getRGB(i, j);
				red = (pixel & 0xff0000) >> 16;//           
				green = (pixel & 0xff00) >> 8;//        
				blue = (pixel & 0xff);//          
				
				if(green - red > 30 && green - blue > 30){//     
					counter++;
				}
			}
		}
		imageMap.put(readFile, counter);//             HashMap 
		
		return imageMap;
	}
3.픽 셀 의 개수 에 따라 그림 정렬
정렬 은 여기 서 만 사용 할 수 있 는 것 이 아니 라 다른 상황 에서 도 사용 할 수 있 습 니 다.(예 를 들 어 파일 생 성 시간 에 따라 정렬 할 수 있 고 정렬 할 수 있 습 니 다)그래서 저 는 순 서 를 추상 류 로 썼 습 니 다.다른 상황 에서 이 추상 류 를 계승 한 다음 에 자신 이 실현 하고 자 하 는 방법 을 구체 적 으로 실현 하면 됩 니 다!구체 적 인 것 은 다음 과 같다.
추상 클래스:

package readcolor;

import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;

public abstract class HashMapSortUtil {
	private HashMap<File, Object> sortMap;//    Map,               Map 
	private String prefix;//  ,          ==> Mus
	
	public abstract LinkedHashMap<File, Object> sortFileMap();//       
	
	public abstract void renameFiles(LinkedHashMap<File, Object> linkedTimeMap);//      

	public HashMap<File, Object> getSortMap() {
		return sortMap;
	}

	public void setSortMap(HashMap<File, Object> sortMap) {
		this.sortMap = sortMap;
	}

	public String getPrefix() {
		return prefix;
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}
}

하위 클래스:

package readcolor;

import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.Set;

public class HashMapSortUtils extends HashMapSortUtil{
	private int counter;//   ,            ==> 1
	private int nameLength;//     ,               0 ==> 3
	private int nameExpansion = 0;//                
	//prefix(     ),counter,nameLength          Mus001
	private HashMap<File, File> tempFileMap = new HashMap<File, File>();//         ,        ,                   HashMap  
	
	public HashMapSortUtils() {//    
		super();
	}
	
	public HashMapSortUtils(HashMap<File, Object> sortMap, Integer counter, Integer nameLength, String prefix) {//    
		super();
		super.setSortMap(sortMap);
		super.setPrefix(prefix);
		this.counter = counter;
		this.nameLength = nameLength;
	}

	/**
	 *                  
	 *   : 
	 *    : 
	 * */
	@Override
	public LinkedHashMap<File, Object> sortFileMap() {
		LinkedHashMap<File,Object> linkedHashMap = new LinkedHashMap<File, Object>();
		Set<Entry<File, Object>> mapEntries = super.getSortMap().entrySet();//           HashMap       
		LinkedList<Entry<File, Object>> timeList = new LinkedList<Entry<File, Object>>(mapEntries);//       List   ,    Collections       
		Collections.sort(timeList, new Comparator<Entry<File, Object>>() {//  Comparator      

			@Override
			public int compare(Entry<File, Object> o1, Entry<File, Object> o2) {
				if(o1.getValue() == o2.getValue()){//              ,           
					return o2.getKey().compareTo(o1.getKey());
				}
				return ((Integer) o2.getValue()).compareTo((Integer)o1.getValue());//              
			}
		});
		
		
		for (Entry<File, Object> entry : timeList) {//           LinkedHashMap ,      HashMap   ,             -o-
			linkedHashMap.put(entry.getKey(), entry.getValue());
		}
		return linkedHashMap;
	}

	/**
	 *         
	 *   :linkedTimeMap:          HashMap
	 *    : 
	 * */
	
	@Override
	public void renameFiles(LinkedHashMap<File, Object> linkedTimeMap) {
		Set<Entry<File,Object>> entrySet = linkedTimeMap.entrySet();
		for (Entry<File, Object> entry : entrySet) {
			renameFile(entry.getKey(), createFileName(entry.getKey())/*           (counter、nameLength、prefix)     */);//     
		}
		//                
		renameTempFiles();
	}

	/**
	 *            (counter、nameLength、prefix)     
	 *   :oldFile:   
	 *    :         
	 * */
	private File createFileName(File oldFile) {
		//       prefix
		String prefix = super.getPrefix();
		//    
		String newFileName = "";
		newFileName += prefix;//       
		int nameLen = String.valueOf(counter).length();//        
		if(nameLen > nameLength){//        ,       (nameLength)       ,             
			nameLength++;
			nameExpansion++;//       ,           ,                
		}
		
		if(nameLen <= nameLength){
			int d_Value = String.valueOf(Math.pow(10, nameLength) - 1).length() - String.valueOf(counter).length() - 2;//       0   ,   2     double     .0
			for (int i = 0; i < d_Value; i++) {
				newFileName += "0";
			}
		}
		newFileName += counter;//          
		
		String oldFileName = oldFile.getName();//        
		String dirName = oldFile.getParentFile().getAbsolutePath();//              
		File newFile = new File(dirName + File.separator + newFileName + oldFileName.substring(oldFileName.lastIndexOf(".")));//           
		counter++;//       +1
		return newFile;
	}
	
	/**
	 *               
	 *   :oldFile:   , newFile:   
	 *    : 
	 * */
	private void renameFile(File oldFile, File newFile) {
		//=================            ,               ,             ,                        =================
		if(oldFile.exists() && oldFile.isFile() && newFile.exists() && newFile.isFile()){
			if(!newFile.getName().equals(oldFile.getName())){
				//===============================         ===============================
				File oldFileTemp = null;
				int fileTempCounter = 0;
				//  do...while...                
				do{
					oldFileTemp = new File(oldFile.getAbsolutePath() + fileTempCounter + System.currentTimeMillis());
					fileTempCounter++;
				}while(oldFileTemp.exists() && oldFileTemp.isFile());
				
				//               
				try{
					new FileServiceImpl().copyFile(oldFile, oldFileTemp);
				}catch (Exception e){
					e.printStackTrace();
				}
				//     
				oldFile.delete();
				//                        HashMap  ,              
				tempFileMap.put(oldFileTemp, newFile);
				return;
			}
		}
		
		//                       ,           
		if(oldFile.exists() && oldFile.isFile()){
			if(oldFile.renameTo(newFile)){
				System.out.println("     :" + oldFile.getAbsolutePath() + "==>" + newFile.getAbsolutePath());
				return;
			}
		}
		
		//            ,                
		System.out.println("====================================     :" + oldFile.getAbsolutePath() + "====================================");
		counter--;
		nameLength -= nameExpansion;
	}
	
	/**
	 *               
	 *   : 
	 *    : 
	 * */
	private void renameTempFiles() {
		Set<Entry<File, File>> entrySet = tempFileMap.entrySet();
		for (Entry<File, File> entry : entrySet) {
			//             
			renameFile(entry.getKey(), entry.getValue());
		}
	}
	
	public int getCounter() {
		return counter;
	}

	public void setCounter(int counter) {
		this.counter = counter;
	}

	public int getNameLength() {
		return nameLength;
	}

	public void setNameLength(int nameLength) {
		this.nameLength = nameLength;
	}
	
}

counter(계수기)와 nameLength(이름 의 길이)는 정렬 과 파일 이름 을 바 꿀 때 자주 사용 되 기 때문에 나 는 그들 을 하위 클래스 에 넣 어서 부모 클래스 의 getter 와 setter 방법 을 여러 번 호출 하지 않도록 했다.제 코드 에 주석 이 명확 하 게 쓰 여 있 지만 일부 동료 들 이 주석 을 보 는 것 에 익숙 하지 않 습 니 다.그럼 제 가 조금 설명 을 드 리 겠 습 니 다.하지만 코드 의 논 리 는 여러분 이 내 려 와 서 보 셔 야 합 니 다!블 로그 에 불편 하면 eclipse 나 아이디어 에 직접 복사 해서 논리 적 으로 분석 할 수 있 습 니 다!
(1)주 방법 이나 다른 방법 에서 이 유형 으로 호출 해 야 합 니 다.이 유형의 구조 방법 을 직접 이용 하여 이 유형 으로 호출 할 수 있 습 니 다.

public HashMapSortUtils(HashMap<File, Object> sortMap, Integer counter, Integer nameLength, String prefix){
	......
}
이 구조 방법 은 정렬 과 이름 을 바 꿔 야 하 는 HashMap 을 이 클래스 의 구성원 변수 에 불 러 옵 니 다.이 클래스 의 모든 방법 은 HashMap 을 호출 할 수 있 으 며,계수기 가 시작 하 는 위치(counter),이름 의 길이(nameLength),이름 접두사(prefix)를 구성원 변수 에 불 러 옵 니 다.그 중에서 HashMap 과 접 두 사 는 부모 클래스 의 변수 에 속 합 니 다.(대부분의 사람들 이 알 고 있다 고 믿 고 나 는 함부로 설명 했다...)
(2)들 어 오 는 HashMap 을 정렬 하 는 방법:

public LinkedHashMap<File, Object> sortFileMap() {
	......
}
이 방법 은 자바 도구 류 Collections 아래 의 sort 방법 을 이용 하여 정렬 하 는 것 입 니 다.주의해 야 할 것 은 마지막 으로 링크 드 HashMap 을 되 돌려 주 는 이 유 는 HashMap 이 무질서 하기 때 문 입 니 다.정렬 이 끝 났 는 지 HashMap 으로 정렬 한 결과 가 있 으 면 정렬 이 예상 하 는 효과 에 이 르 지 못 할 수 있 습 니 다.
(3)정렬 된 HashMap 의 파일 이름 을 바 꾸 는 방법:

public void renameFiles(LinkedHashMap<File, Object> linkedTimeMap) {
	......
}
이 방법 은 주로 두 단계 로 나 뉜 다.a.createFileName 방법 으로 이전에 설정 한 prefix(접두사),nameLength(이름 의 길이),counter(계수기)를 이용 하여 새로운 이름 을 구성한다.b.HashMap 의 모든 entry 노드 를 renameFile 방법 으로 이름 을 직접 바 꿀 수 있 는 지 판단 합 니 다.이름 을 직접 바 꿀 수 있다 면 이름 을 바 꿀 수 있 습 니 다.이름 을 바 꿀 파일 이 이미 존재 한다 면 원본 파일 copy 를 한 부 만 들 고 복사 파일 과 새로운 이름 방법 을 HashMap 에서 프로그램의 c 단계 에서 이 부분 파일 의 이름 을 바 꿀 수 있 습 니 다!c.이전에 이름 을 바 꾸 지 않 았 던 원본 파일 을 renameTempFiles 방법 으로 통일 적 으로 이름 을 바 꿉 니 다!
4.파일 작업 의 도구 클래스
파일 작업 은 하나의 공공 유형 으로 파일 의 복사,삭제,모든 파일 가 져 오기,폴 더 만 들 기 등 을 할 수 있 습 니 다.모두 가 공공 적 인 방법 으로 쓸 수 있 습 니 다.여러분 은 이런 역할 을 스스로 이해 할 수 있 습 니 다.여 기 는 더 이상 군말(히히,또 게 으 름 을 피 울 수 있 습 니 다)이 많 지 않 습 니 다.하지만 저 는 잘못된 시범 입 니 다.저 는 인터페이스 방식 으로 이 루어 졌 습 니 다.진정한 생산 에서 이렇게 하지 않 을 것 이다.왜냐하면 파일 조작 은 기본적으로 변 하지 않 기 때문이다.여기 서 나 는 단순히 인터페이스의 조작 에 연락 하고 싶 을 뿐이다.그러면 쓸데없는 말 을 많이 하지 않 고 코드 를 직접 올 리 는 것 은 모두 파일 작업 의 기본 코드 이다.
파일 작업 의 인터페이스:

package readcolor;

import java.io.File;
import java.util.List;

public interface FileService {
	void copyFile(String sourcePath, String targetPath) throws Exception;
	
	void copyFile(File sourceFile, File targetFile) throws Exception;
	
	void mkDirs(String path) throws Exception;
	
	List<File> getAllFiles(String sourcePath);
	
	void removeFiles(String path);
	
	void removeFiles(File sourceFile);
}

파일 작업 의 구현 클래스:

package readcolor;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

public class FileServiceImpl implements FileService{

	@Override
	public void copyFile(String sourcePath, String targetPath) throws Exception {
		copyFile(new File(sourcePath), new File(targetPath));
		
	}

	@Override
	public void copyFile(File sourceFile, File targetFile) throws Exception {
		FileInputStream fis = new FileInputStream(sourceFile);
		FileOutputStream fos = new FileOutputStream(targetFile);
		
		byte[] buffer = new byte[1024];
		int len = 0;
		
		while((len = fis.read(buffer)) != -1){
			fos.write(buffer, 0, len);
			fos.flush();
		}
		
		fos.close();
		fis.close();
	}

	@Override
	public void mkDirs(String path) throws Exception {
		File destFile = new File(path);
		if(!destFile.exists()){
			destFile.mkdirs();
		}
	}

	@Override
	public List<File> getAllFiles(String sourcePath) {
		ArrayList<File> files = new ArrayList<File>();
		File file = new File(sourcePath);
		if(file.exists() && !file.isHidden()){
			if(file.isFile()){
				files.add(file);
			}
			
			if(file.isDirectory()){
				File[] fs = file.listFiles();
				for (File f : fs) {
					if(!f.isHidden()){
						if(f.isFile()){
							files.add(file);
						}
						
						if(f.isDirectory()){
							files.addAll(getAllFiles(sourcePath + File.separator + f.getName()));
						}
					}
				}
			}
		}
		return files;
	}

	@Override
	public void removeFiles(String path) {
		removeFiles(new File(path));
	}

	@Override
	public void removeFiles(File sourceFile) {
		if (!sourceFile.isDirectory()){
			if(sourceFile.delete()) System.out.println("    :" + sourceFile.getAbsolutePath() + "  ");
		}else{
			File[] files = sourceFile.listFiles();
			
			for (File file : files) {
				if(file.isDirectory()){
					removeFiles(file);
					if(file.delete()) System.out.println("     :" + file.getAbsolutePath() + "  ");
				}else{
					if(file.delete()) System.out.println("    :" + file.getAbsolutePath() + "  ");
				}
			}
		}
	}
}

좋 습 니 다.모든 준비 가 다 되 었 습 니 다.그러면 우 리 는 코드 를 직접 실행 하여 효과 가 어떤 지 봅 시다.
먼저 그림 준비 하기:
在这里插入图片描述
그리고 파일 의 경 로 를 설정 합 니 다:
在这里插入图片描述
자바 프로그램 실행:
在这里插入图片描述
모든 파일 이 정렬 되 어 있 고 이름 이 바 뀌 었 음 을 볼 수 있 습 니 다.실제 효 과 를 보십시오.
在这里插入图片描述
앞 에 그림 이 좀 푸 르 게 나 올 것 같 지 않 아 요?이 프로그램 은 반복 적 으로 실 행 될 수 있 습 니 다.잠시 이름 을 짓 는 데 실패 한 상황 이 발생 하지 않 았 습 니 다.만약 에 친구 가 시험 한 후에 잘못 보고 하면 메 시 지 를 남 겨 주세요.무슨 문제 인지 보고 다시 최적화 할 수 있 는 지 보 겠 습 니 다.머리 에서 떨 어 지 는 냄새 가 난다)
총결산
마지막 으로 우 리 는 몇 줄 의 코드 를 조금 바 꾼 다음 에 모든 그림 을 녹색 픽 셀 점 만 출력 하여 직관 적 인 느낌 을 줄 수 있다.

package readcolor;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;

import javax.imageio.ImageIO;

public class ReadColor {
	private static int count = 0;
	public static void main(String[] args) {
		HashMap<File, Object> imageMap = new HashMap<File, Object>();// hashMap                
		File fileDir = new File("D:\\Download\\TestFile");//           
		File[] listFiles = fileDir.listFiles();
		for (File readFile : listFiles) {
			getImagePixel(readFile, imageMap);//               
		}
		
		HashMapSortUtils hashMapSortUtils = new HashMapSortUtils(imageMap, 1, 3, "Mus");
		LinkedHashMap<File,Object> sortFileMap = hashMapSortUtils.sortFileMap();//               
		hashMapSortUtils.renameFiles(sortFileMap);//          (                 >o<)
		
		System.out.println(imageMap);
	}

	private static HashMap<File, Object> getImagePixel(File readFile, HashMap<File, Object> imageMap) {
		int red = 0;//        
		int green = 0;//        
		int blue = 0;//        
		int counter = 0;//     
		
		BufferedImage bi = null;
		try {
			bi = ImageIO.read(readFile);//  ImageIO     ,       RGB  
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		int width = bi.getWidth();//       
		int height = bi.getHeight();//       
		int minx = bi.getMinX();//         x 
		int miny = bi.getMinY();//         y 
		
		for(int i = minx; i < width; i++){
			for(int j = miny; j < height; j++){
				int pixel = bi.getRGB(i, j);
				red = (pixel & 0xff0000) >> 16;//           
				green = (pixel & 0xff00) >> 8;//        
				blue = (pixel & 0xff);//          
				
				if(green - red > 30 && green - blue > 30){//     
					counter++;
				}else{
					bi.setRGB(i, j, 0xffffff);
				}
			}
		}
		imageMap.put(readFile, counter);//             HashMap 
		
		try {
			ImageIO.write(bi, "jpg", new File("D:\\Download\\TestFile1\\" + count +".jpg"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		count++;
		return imageMap;
	}
}
그림 의 비 녹색 픽 셀 점 을 흰색 으로 수정 한 다음 새 폴 더 에 저장 하여 어떤 효과 가 있 는 지 보 세 요.
在这里插入图片描述
녹색 픽 셀 만 추출 한 것 이 아 닙 니까?여러분 은 이 를 바탕 으로 자신 이 좋아 하 는 색 을 선택 하여 정렬 할 수 있 습 니 다.어쨌든 내 가 이 프로그램 을 내 친구 에 게 주 었 을 때,그 에 게 30 분 동안 감 사 를 받 았 다.모두 가 혼자 놀 수 있 을 뿐,절대 다른 사람의 하 드 디스크 를 함부로 건 드 리 지 마라!마지막 으로 프로그램 은 실제 적 인 사용 가치 가 없습니다.새로운 방법 이나 기 교 를 배 웠 을 뿐 입 니 다.실제로 저 는 이미지 처 리 를 할 때 포 토 샵 을 직접 사용 하여 조작 합 니 다.하하 하!)
자 바 는 그림 속 녹색 픽 셀 점 의 많 고 적 음 에 따라 정렬 하 는 글 을 소개 합 니 다.자 바 는 녹색 픽 셀 점 의 정렬 내용 에 대해 서 는 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기