java 文字 图片_java实现文字堆砌图片?

博客内容讲述了作者尝试使用Java实现Python代码中文字堆砌成图片的效果,但遇到了高度显示不全、第一行错位和左侧多余字符的问题。作者分享了Java版本的代码,并希望得到大佬的指教。
摘要由CSDN通过智能技术生成

偶然逛知乎看到一个代码,实现了用文字堆砌图片,效果如下:

(图侵删@xlzd)

8d876cdaf6894c0bd6988c7b543d8792.png

a51a5f0ed7f9ea43a4c31685b7b31c40.png

源码是py写的,无奈没学过python,大概看懂了一些思路,假设字体是10px,那么就用一个字代替10*10的像素,颜色是这100个像素的RGB色平均值,自己尝试用java实现了一下,发现有一些问题,思考很久,没发现问题所在,有没有大佬指点下啊.

以下是源码:

#!/usr/bin/env python

# encoding=utf-8

from __future__ import print_function, unicode_literals

from collections import namedtuple

from itertools import cycle

import jinja2

from PIL import Image

Point = namedtuple('Point', ['x', 'y'])

Pixel = namedtuple('Pixel', ['r', 'g', 'b'])

RenderItem = namedtuple('RenderItem', ['color', 'char'])

RenderGroup = list

HTMLImage = list

TEMPLATE = '''

{{ title }}

body {

margin: 0px; padding: 0px; line-height:100%; letter-spacing:0px; text-align: center;

min-width: {{width}}px;

width: auto !important;

font-size: {{size}}px;

background-color: #{{background}};

font-family: {{font_family}};

}

{% for group in html_image %}

{% for item in group %}{{ item.char }}{% endfor %}

{% endfor %}

'''

_c = cycle(r'/-\|')

def _progress_callback(percent):

if percent == 100:

print('\rDone! ')

else:

import sys, time

lca = getattr(_progress_callback, '_last_call_at', 0)

if time.time() - lca > 0.1:

_progress_callback._last_call_at = time.time()

sys.stdout.write('\r{} progress: {:.2f}%'.format(_c.next(), percent))

sys.stdout.flush()

class Img2HTMLConverter(object):

def __init__(self,

font_size=10,

char='䦗',

background='#000000',

title='img2html by xlzd',

font_family='monospace',

progress_callback=None):

self.font_size = font_size

self.background = background

self.title = title

self.font_family = font_family

if isinstance(char, str):

char = char.decode('utf-8')

self.char = cycle(char)

self._prg_cb = progress_callback or _progress_callback

def convert(self, source):

image = Image.open(source)

width, height = image.size

row_blocks = int(round(float(width) / self.font_size))

col_blocks = int(round(float(height) / self.font_size))

html_image = HTMLImage()

progress = 0.0

step = 1. / (col_blocks * row_blocks)

for col in xrange(col_blocks):

render_group = RenderGroup()

for row in xrange(row_blocks):

pixels = []

for y in xrange(self.font_size):

for x in xrange(self.font_size):

point = Point(row * self.font_size + x, col * self.font_size + y)

if point.x >= width or point.y >= height:

continue

pixels.append(Pixel(*image.getpixel(point)[:3]))

average = self.get_average(pixels=pixels)

color = self.rgb2hex(average)

render_item = RenderItem(color=color, char=self.char.next())

render_group.append(render_item)

progress += step

self._prg_cb(progress * 100)

html_image.append(render_group)

self._prg_cb(100)

return self.render(html_image)

def render(self, html_image):

template = jinja2.Template(TEMPLATE)

return template.render(

html_image=html_image,

size=self.font_size,

background=self.background,

title=self.title,

font_family=self.font_family,

width=self.font_size * len(html_image[0]) * 2

)

@staticmethod

def rgb2hex(pixel):

return '{:02x}{:02x}{:02x}'.format(*pixel)

@staticmethod

def get_average(pixels):

r, g, b = 0, 0, 0

for pixel in pixels:

r += pixel.r

g += pixel.g

b += pixel.b

base = float(len(pixels))

return Pixel(

r=int(round(r / base)),

g=int(round(g / base)),

b=int(round(b / base)),

)

我的效果如下:

73072935af7106a1dc9b6a1308adf8f3.png

f14149f144dda99552f19fb204f7f860.png

可以看到高度只有差不多一半,第一行错位,左边莫名其妙多了很多黑色的字,可能跟图片大小有关,但是换大一点的图片后,上述问题依然存在

下面是代码:

public class Img2Html {

public static void convert(File imgPath, File resultPath, int fontSize,String chars) throws Exception{

BufferedImage bufferedImage = null;

BufferedWriter bufferedWriter = null;

try {

bufferedImage = ImageIO.read(imgPath);

bufferedWriter = new BufferedWriter(new FileWriter(resultPath));

//宽度

int width = bufferedImage.getWidth();

//高度

int height = bufferedImage.getHeight();

//

int[] rgb = new int[3];

//X轴字的个数

int rowBlockNum = Math.round((float)height/fontSize);

//Y轴字的个数

int colBlockNum = Math.round((float)width/fontSize);

//背景颜色

bufferedWriter.write("\n");

bufferedWriter.write("

\n");

bufferedWriter.write("

bufferedWriter.write("div{\n");

bufferedWriter.write("background-color:#272822;\n");

bufferedWriter.write("font-size:"+ fontSize +"px;\n");

bufferedWriter.write("font-family:monospaced");

bufferedWriter.write("}\n");

bufferedWriter.write("");

bufferedWriter.write("

\n");

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

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

for (int y = 0; y < fontSize; y++) {

for (int x = 0; x < fontSize; x++) {

//越界无视

if(x+j*fontSize >= width || +i*fontSize >= height){

continue;

}

int pixel = bufferedImage.getRGB(x+j*fontSize, y+i*fontSize);

//获取像素点RGB值

rgb[0] += (pixel & 0xff0000) >> 16;

rgb[1] += (pixel & 0xff00) >> 8;

rgb[2] += (pixel & 0xff);

}

}

//求平均值

int[] rgbAvg = getAvg(rgb,fontSize);

//转换成16进制

String rgbHex = rgb2hex(rgbAvg);

System.out.println(rgbAvg[0]+","+rgbAvg[1]+","+rgbAvg[2] + " hex:" + rgbHex);

bufferedWriter.write(""+ chars +"");

if (j == colBlockNum-1)

bufferedWriter.write("
\n");

//重置

rgb[0] = 0;

rgb[1] = 0;

rgb[2] = 0;

}

}

bufferedWriter.write("\n

");

bufferedWriter.write("\n");

bufferedWriter.write("\n");

}catch (Exception e){

e.printStackTrace();

}finally {

bufferedWriter.close();

}

}

public static String toHex(int num){

String hex = Integer.toHexString(num);

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

return hex;

}else {

return "0"+hex;

}

}

public static int[] getAvg(int[] rgb,int fontSize) {

int[] avg = new int[3];

avg[0] = rgb[0] / (fontSize * fontSize);

avg[1] = rgb[1] / (fontSize * fontSize);

avg[2] = rgb[2] / (fontSize * fontSize);

return avg;

}

public static String rgb2hex(int[] rgbAvg){

String rgbHex = "#" + toHex(rgbAvg[0]) + toHex(rgbAvg[1]) + toHex(rgbAvg[2]);

return rgbHex;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值