ccf画图java详细解析,CCF-画字符-详细的注释

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.StringTokenizer;

public class Main3 {

static int R, G, B;

static String reset = "\\x1B\\x5B\\x30\\x6D";

public static void main(String[] args) {

//test();

run();

}

public static void test() {

//测试代码

}

public static void run() {

FastIO io = new FastIO();

io.init(System.in);

int width = io.nextInt(), height = io.nextInt();

int pw = io.nextInt(), qh = io.nextInt();

int[][][] image = new int[height][width][3];

for (int i = 0; i < height; i++) {

for (int j = 0; j < width; j++) {

hexToRGB(io.next());

image[i][j][0] = R;

image[i][j][1] = G;

image[i][j][2] = B;

}

}

int count = pw * qh;//一个小块中像素点的数量

int rAvg = 0, gAvg = 0, bAvg = 0;

int preR = 0, preG = 0, preB = 0;

StringBuilder result = new StringBuilder();

boolean first = true;

for (int i = 0; i < height; i += qh) {

for (int j = 0; j < width; j += pw) {

int rSum = 0, gSum = 0, bSum = 0;

for (int y = i; y < i + qh; y++) {

for (int x = j; x < j + pw; x++) {

rSum += image[y][x][0];

gSum += image[y][x][1];

bSum += image[y][x][2];

}

}

rAvg = rSum / count;

gAvg = gSum / count;

bAvg = bSum / count;

if (first) {

//一行的开始,此时背景色已经是默认色,所以如果该块等于默认色,则什么都不做。

// 只有该块的颜色不等于默认色的时候才输出默认色

if (!(rAvg == 0 && gAvg == 0 && bAvg == 0)) {

changeBackground(rAvg, gAvg, bAvg, result);

}

first = false;

} else if (!(rAvg == preR && gAvg == preG && bAvg == preB)) {

//如果该块的颜色不等于上一块的颜色,且等于默认色输出重置序列

if (rAvg == 0 && gAvg == 0 && bAvg == 0) {

result.append(reset);

} else {

//如果该块的颜色不等于上一块的颜色,且不等于默认色,那么改变输出背景色序列

changeBackground(rAvg, gAvg, bAvg, result);

}

}

result.append("\\x20");

preR = rAvg;

preG = gAvg;

preB = bAvg;

}

//如果该行结束后时的背景色不等于默认色,则输出重置序列

if (!(rAvg == 0 && gAvg == 0 && bAvg == 0)) {

result.append(reset);

}

first = true;

//添加一个换行符

result.append("\\x0A");

}

//只在最后输出结果,而不是每一行就输出一次,这样可以减少IO次数,节约用时

System.out.print(result.toString());

}

/**

* 将颜色的16进制转换成(R,G,B)的形式

* @param hex 颜色的16进制值

*/

public static void hexToRGB(String hex) {

if (hex.length() == 4) {

//#abc->#aabbcc的情况

R = Integer.parseInt(hex.substring(1, 2) + hex.substring(1, 2), 16);

G = Integer.parseInt(hex.substring(2, 3) + hex.substring(2, 3), 16);

B = Integer.parseInt(hex.substring(3, 4) + hex.substring(3, 4), 16);

} else if (hex.length() == 2) {

//#a->#aaaaaa的情况

R = Integer.parseInt(hex.substring(1,2)+hex.substring(1,2), 16);

G = R;

B = R;

} else {

//#aabbcc的情况

R = Integer.parseInt(hex.substring(1, 3), 16);

G = Integer.parseInt(hex.substring(3, 5), 16);

B = Integer.parseInt(hex.substring(5, 7), 16);

}

}

/**

* 改变背景色

*/

public static void changeBackground(int R, int G, int B, StringBuilder hexOut) {

// ESC[48;2

hexOut.append("\\x1B\\x5B\\x34\\x38\\x3B\\x32\\x3B");

getHexOrder(R,hexOut);

// 3B对应字符 ;

hexOut.append("\\x3B");

getHexOrder(G, hexOut);

hexOut.append("\\x3B");

getHexOrder(B, hexOut);

// 6D 对应字符m

hexOut.append("\\x6D");

}

/**

* 获取一个分量每位对应的16进制,并且按照输出的顺序进行拼接

* @param a 颜色int值

*/

public static void getHexOrder(int a, StringBuilder hexOut) {

if (a >= 100) {

//该颜色分量有3位

hexOut.append("\\x");

// 48对应ACSII字符表中的'0' 字符,因为我们最终的输出时一个字符对应的转义序列,而不是10进制的int值的16进制,所以需要加上48

hexOut.append(Integer.toHexString(a / 100+48));

hexOut.append("\\x");

hexOut.append(Integer.toHexString(a / 10 % 10+48));

hexOut.append("\\x");

hexOut.append(Integer.toHexString(a % 10+48));

} else if (a >= 10) {

//颜色分量有2位

hexOut.append("\\x");

hexOut.append(Integer.toHexString(a / 10+48));

hexOut.append("\\x");

hexOut.append(Integer.toHexString(a % 10+48));

}else {

//颜色分量只有一位

hexOut.append("\\x");

hexOut.append(Integer.toHexString(48 + a));

}

}

static class FastIO {

BufferedReader reader;

StringTokenizer tokenizer;

void init(InputStream inputStream) {

reader = new BufferedReader(new InputStreamReader(inputStream));

tokenizer = new StringTokenizer("");

}

//读入一个字符串

String next() {

while (!tokenizer.hasMoreTokens()) {

try {

tokenizer = new StringTokenizer(reader.readLine());

} catch (IOException e) {

e.printStackTrace();

}

}

return tokenizer.nextToken();

}

//读入一整行

String nextLine() {

while (!tokenizer.hasMoreElements()) {

try {

tokenizer = new StringTokenizer(reader.readLine());

} catch (IOException e) {

e.printStackTrace();

}

}

return tokenizer.nextToken("\n");

}

//读入int类型数据

int nextInt() {

return Integer.parseInt(next());

}

//读入double类型数据

double nextDouble() {

return Double.parseDouble(next());

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值