Jump to content
Sign in to follow this  
MattyD

AsciiIt

Recommended Posts

MattyD

Hi all,

Version 2! because the square font movement failed.

Also it is faster and allows you so scale the picture up and down.

Cheers,

Matt

#cs
AsciiIt v2 - MattyD
_AsciiIt($sName, $aiChars, $nRatio = 1.4, $iTargetWidth = -1, $iTargetHeight = -1, $aiCrop = 0
$sName - Path to a 2, 16 or 256 colour bitmap file.
$aiChars - An array of characters to replace the colours in the image. The array indecies correspond to the colour numbers in the bitmap.
    If no character is specified for a colour, a space is used as a placeholder.
    If no array is specified, random characters will be used for all colours.
$nRatio - Specifies how far to sretch the image (to compensate for fonts not having square characters).
          If $nRatio is 0 The output size is specified by $iTargetWidth and $iTargetHeight
    Default is 1.4
$iTargetWidth and $iTargetHeight - In number of characters. The output image will be as large as possible within these bounds.
    If $nRatio > 0 then the image will stay in proportion.
       Default - $iTargetHeight = Original image size
         - $iTargetWidth = Original image width * $nRatio
$aiCrop - In number of pixels. A four element array that specifies how far to crop the image (before resizing).
    $aiCrop[0] - Left
    $aiCrop[1] - Right
    $aiCrop[2] - Top
    $aiCrop[3] - Bottom
#ce
#include <WinAPI.au3>
Local $aiChars[256]
$aiChars[0] = "0"
$aiChars[1] = "1"
$aiChars[2] = "2"
$aiChars[3] = "3"
$aiChars[4] = "4"
$aiChars[5] = "5"
$aiChars[6] = "6"
$aiChars[7] = "7"
$aiChars[8] = "8"
$aiChars[9] = "9"
$aiChars[10] = "!"
$aiChars[11] = "@"
$aiChars[12] = "#"
$aiChars[13] = "$"
$aiChars[14] = "%"
$aiChars[15] = "^"
Local $aiCrop[4] = [105, 27, 8, 31]
Local $test = _AsciiIt("test.bmp", $aiChars, 1.4, 100, -1, $aiCrop)
ConsoleWrite($test & @CRLF)
Func _AsciiIt($sName, $aiChars = 0, $nRatio = -1, $iTargetWidth = -1, $iTargetHeight = -1, $aiCrop = 0)
Local $hFile, $iRead, $iImgDataOffset, $aiAttributes, $iBitCount, $iWidth, $iHeight, $aiImage, $sImage
$hFile = _WinAPI_CreateFile($sName, 2, 2)
If Not $hFile Then Return SetError(@error, @extended, $hFile)
$iImgDataOffset = _AsciiIt_ReadFileHeader($hFile)
If Not $iImgDataOffset Then Return _WinAPI_CloseHandle($hFile)
$iRead = @extended
$aiAttributes = _AsciiIt_ReadDIBHeader($hFile)
$iRead += @extended
If Not IsArray($aiAttributes) Then Return _WinAPI_CloseHandle($hFile)
If $aiAttributes[2] <> 1 Or $aiAttributes[4] Then Return SetError(2, 0, False)
;_ArrayDisplay($aiAttributes)
$iWidth = $aiAttributes[0]
$iHeight = $aiAttributes[1]
$iBitCount = $aiAttributes[3]
$aiImage = _AsciiIt_Scan($hFile, $iImgDataOffset, $iRead, $iWidth, $iHeight, $iBitCount)
If Not IsArray($aiImage) Then Return _WinAPI_CloseHandle($hFile)
If $nRatio < 0 Then $nRatio = 1.4
If $iTargetWidth < 1 Then $iTargetWidth = $iWidth * $nRatio
If $iTargetHeight < 1 Then $iTargetHeight = $iHeight
If Not IsArray($aiCrop) Then Dim $aiCrop[4]
$aiImage = _AsciiIt_Resize($aiImage, $nRatio, $iTargetWidth, $iTargetHeight, $aiCrop)
If IsArray($aiChars) Then
  ReDim $aiChars[2 ^ $iBitCount]
  For $i = 0 To UBound($aiChars) - 1
   If Not $aiChars[$i] Then $aiChars[$i] = " "
  Next
Else
  Dim $aiChars[2 ^ $iBitCount]
  For $i = 0 To UBound($aiChars) - 1
   $aiChars[$i] = Chr(Random(32, 126, 1))
  Next
EndIf
For $i = 0 To UBound($aiImage) - 1
  For $j = 0 To UBound($aiImage, 2) - 1
   $sImage &= $aiChars[$aiImage[$i][$j]]
  Next
  $sImage &= @CRLF
Next
_WinAPI_CloseHandle($hFile)
Return $sImage
EndFunc
Func _AsciiIt_ReadFileHeader($hFile)
Local $tBuffer, $iRead, $fResult
$tBuffer = DllStructCreate("byte sig[2]; align 2; dword filesize; word rsv[2]; dword offset")
$fResult = _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), DllStructGetSize($tBuffer), $iRead)
If Not $iRead Then Return SetError(@error, @extended, $fResult)
If DllStructGetData($tBuffer, "sig") <> Binary("0x424D") Then Return SetError(1, 0, False)
Return SetExtended($iRead, DllStructGetData($tBuffer, "offset"))
EndFunc
Func _AsciiIt_ReadDIBHeader($hFile)
Local $tBuffer, $iRead, $fResult, $aiAttributes[6]
$tBuffer = DllStructCreate("align 2; dword DIBsize; dword width; dword height; word planes; word bpp; " & _
   "dword compression; dword imgsize; dword xppm; dword yppm; dword numcolours; dword impcolours")
$fResult = _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), DllStructGetSize($tBuffer), $iRead)
If Not $iRead Then Return SetError(@error, @extended, $fResult)
$aiAttributes[0] = DllStructGetData($tBuffer, "width")
$aiAttributes[1] = DllStructGetData($tBuffer, "height")
$aiAttributes[2] = DllStructGetData($tBuffer, "planes")
$aiAttributes[3] = DllStructGetData($tBuffer, "bpp")
$aiAttributes[4] = DllStructGetData($tBuffer, "compression")
$aiAttributes[5] = DllStructGetData($tBuffer, "numcolours")
Return SetExtended($iRead, $aiAttributes)
EndFunc
Func _AsciiIt_Scan($hFile, $iImgDataOffset, $iRead, $iWidth, $iHeight, $iBitCount)
Local $tBuffer, $fResult, $iLineSize, $aiImage[$iHeight][$iWidth], $iByte, $iyPxl, $bImgData
$tBuffer = DllStructCreate("byte[" & $iImgDataOffset - $iRead & "]")
$fResult = _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), DllStructGetSize($tBuffer), $iRead)
If Not $iRead Then Return SetError(@error, @extended, $fResult)
$iLineSize = Ceiling($iWidth * ($iBitCount / 8) / 4) * 4
;ConsoleWrite("Line Size = " & $iLineSize & ", Lines = " & $iHeight & ", Pic Size = " & $iLineSize * $iHeight & @CRLF)
;ConsoleWrite("Width = " & $iWidth & ", Height = " & $iHeight & ", Pxls = " & $iWidth * $iHeight & @CRLF)
$tBuffer = DllStructCreate("align 2;byte[" & $iLineSize * $iHeight & "]")
$fResult = _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), DllStructGetSize($tBuffer), $iRead)
If Not $iRead Then Return SetError(@error, @extended, $fResult)
$bImgData = DllStructGetData($tBuffer, 1)
For $i = 1 To $iHeight
  ;ConsoleWrite("Row" & $i & @CRLF)
  For $j = 1 To $iLineSize
   ;ConsoleWrite(" Byte" & $j & @CRLF)
   $iByte = BinaryMid($bImgData, ($i - 1) * $iLineSize + $j, 1)
   ;ConsoleWrite($i & "," & $j & @CRLF)
   For $k = 0 To 8 / $iBitCount - 1
    $iyPxl = ($j - 1) * (8 / $iBitCount - 1) + ($j - 1) + $k
    If $iyPxl >= $iWidth Then ExitLoop 2
    ;ConsoleWrite("  value" & $iyPxl & " " & $iWidth & @CRLF)
    $iByte = BitRotate($iByte, $iBitCount, "B")
    $aiImage[$iHeight - $i][$iyPxl] = BitAND($iByte, (2 ^ $iBitCount) - 1)
   Next
  Next
Next
;_ArrayDisplay($aiImage)
Return $aiImage
EndFunc
Func _AsciiIt_Resize($aiImage, $nRatio, $iWidth, $iHeight, $aiCrop)
If $iWidth < 1 Or $iHeight < 1 Or $nRatio < 0 Or UBound($aiCrop) <> 4 Then Return SetError(3, 0, $aiImage)
Local $iHPerc, $iWPerc, $iHRef, $iWRef
$iHPerc = $iHeight / (UBound($aiImage) - ($aiCrop[2] + $aiCrop[3]))
$iWPerc = $iWidth / (UBound($aiImage, 2) - ($aiCrop[0] + $aiCrop[1]))
If $nRatio Then
  If ($iWPerc / $nRatio) * (UBound($aiImage) - ($aiCrop[2] + $aiCrop[3])) < $iHeight Then
   $iHPerc = $iWPerc / $nRatio
   ;ConsoleWrite("Snap to Width" & @CRLF)
  Else
   $iWPerc = $iHPerc * $nRatio
   ;ConsoleWrite("Snap to Height" & @CRLF)
  EndIf
EndIf
Local $aiResizedImg[(UBound($aiImage) - ($aiCrop[2] + $aiCrop[3])) * $iHPerc ][(UBound($aiImage, 2) - ($aiCrop[0] + $aiCrop[1])) * $iWPerc]
;ConsoleWrite(UBound($aiResizedImg, 2) & " x " & UBound($aiResizedImg) & @CRLF)
For $i = 0 To UBound($aiResizedImg) - 1
  $iHRef = Round(($i + 1) / $iHPerc) - 1 + $aiCrop[2]
  If $iHRef < 0 Then $iHRef = 0
  For $j = 0 To UBound($aiResizedImg, 2) - 1
   $iWRef = Round(($j + 1) / $iWPerc) - 1 + $aiCrop[0]
   If $iWRef < 0 Then $iWRef = 0
   $aiResizedImg[$i][$j] = $aiImage[$iHRef][$iWRef]
  Next
Next
Return $aiResizedImg
EndFunc

and another output file (this time more in proportion) - source was a 16 colour screenshot at 25% of the original size

asciiIt.txt

Edited by MattyD

Share this post


Link to post
Share on other sites
trancexx

Oh, very nice!

edit: guess who's this, hah :unsure:

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
MattyD

lovely! thankyou both :unsure:. Now to start a square fonts movement...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.