Color ASCII art converter

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
Qlink
Posts: 79
Joined: Jun 06, 2007 15:21

Color ASCII art converter

Post by Qlink »

I'm writing a program to convert 24 bit BMP files to color ASCII art. So far, all it does is display the image, which has to be 640x480 or less, but the quality is pretty good.

Code: Select all

'************************
'* iCon Image Converter *
'*  > by Pharoah/Qlink  *
'************************
'Version 0.75 unoptimized

if command(1) = "ver" then
	print "Icon 0.75 unoptimized"
	end
elseif command(1) = "grad" then
	print "Icon image converter"
	print "Gradients:"
	print "    0                  - Block characters"
	print "    1                  - Round characters"
	print "    2                  - Libcaca gradient"
	print "    3                  - All low ASCII characters"
	print "    custom= [gradient] - Custom gradient"
	end
elseif command(1) <> "view" then
	print "Icon Image Converter"
	print "Commands:"
	print "    view [file] [gradient] - Show image"
	print "    ver                    - Show application version"
	print "    grad                   - Show gradient list"
	end
end if

dim path as string = command(2)
dim gradients(4) as string, gradient as string
gradients(0) = chr(177) + chr(178) + chr(219)
gradients(1) = " .:coCO8@" 					
gradients(2) = " .:;tSX%@B8"					
for i as integer = 32 to 127: gradients(3) += chr(i): next

if command(3) = "custom=" then
	gradient = command(4)
else
	gradient = gradients(valint(command(3)))
end if

type rgbType
	blue as ubyte
	green as ubyte
	red as ubyte
end type
type colorType
	union
		all as integer
		component as rgbType
	end union
end type
type charType
	mean as rgbType
	code as ubyte
	fg as ubyte
	bg as ubyte
end type
declare function average4(x as integer, y as integer, w as integer, h as integer) as rgbType
declare function average24(x as integer, y as integer, w as integer, h as integer, buffer as any ptr) as rgbType

screen 12
dim shared colors(15) as colorType
colors(0).all = &h000000
colors(1).all = &h0000AA
colors(2).all = &h00AA00
colors(3).all = &h00AAAA
colors(4).all = &hAA0000
colors(5).all = &hAA00AA
colors(6).all = &hAA5500
colors(7).all = &hAAAAAA

colors(8).all = &h555555
colors(9).all = &h5555FF
colors(10).all = &h55FF55
colors(11).all = &h55FFFF
colors(12).all = &hFF5555
colors(13).all = &hFF55FF
colors(14).all = &hFFFF55
colors(15).all = &hFFFFFF

'Chars 177, 178, 219
dim lookup(256 * len(gradient) - 1) as charType
var current = 0
for f as ubyte = 0 to 15
	for b as ubyte = 0 to 15
		for p as ubyte = 1 to len(gradient)
			dim c as ubyte = asc(mid(gradient, p, 1))
			locate 1,1
			color f, b
			print chr(c);
			lookup(current).mean = average4(0,0,8,16)
			lookup(current).fg = f
			lookup(current).bg = b
			lookup(current).code = c
			current += 1
		next
	next
next
color 15
screen 18, 24
dim source as any ptr = imageCreate(640, 480, 0)
bload path, source
screen 12
width 80, 30
dim sample as rgbType
cls
randomize timer
for row as integer = 1 to 30
	for column as integer = 1 to 79
		sample = average24((column-1)*8, (row - 1)*16, 8, 16, source)
		var bestDistance = 1024
		var best = 0
		for i as integer = 0 to 256 * len(gradient) - 1
			var distance = abs(sample.red - lookup(i).mean.red) + _
						   abs(sample.green - lookup(i).mean.green) + _
						   abs(sample.blue - lookup(i).mean.blue)
			if distance < bestDistance then
				best = i
				bestDistance = distance
			elseif distance = bestDistance then
				if rnd > .5 then best = i
			end if
		next i
		color lookup(best).fg, lookup(best).bg
		print chr(lookup(best).code);
	next
	color ,0
	print " ";
next
sleep

function average4(x as integer, y as integer, w as integer, h as integer) as rgbType
	dim as rgbtype result
	dim as integer red, green, blue
	dim as ubyte sample
	for horiz as integer = 0 to w - 1
		for vert as integer = 0 to h - 1
			sample = point(x + horiz, y + vert)
			red += colors(sample).component.red
			green += colors(sample).component.green
			blue += colors(sample).component.blue
		next
	next
	result.red   = red   \ (w * h)
	result.green = green \ (w * h)
	result.blue  = blue  \ (w * h)
	return result
end function

function average24(x as integer, y as integer, w as integer, h as integer, buffer as any ptr) as rgbType
	dim as rgbtype result
	dim as colorType sample
	dim as integer red, green, blue
	for horiz as integer = 0 to w - 1
		for vert as integer = 0 to h - 1
			sample.all = point(x + horiz, y + vert, buffer)
			red += sample.component.red
			green += sample.component.green
			blue += sample.component.blue
		next
	next
	result.red   = red   \ (w * h)
	result.green = green \ (w * h)
	result.blue  = blue  \ (w * h)
	return result
end function
Post Reply