package com.bachors.img2ascii; import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.graphics.Color; import android.os.AsyncTask; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; import static java.lang.Math.round; /** * Created by Bachors on 10/31/2017. * https://github.com/bachors/Android-Img2Ascii */ public class Img2Ascii { private String[] chars = {"@", "#", "+", "\\", ";", ":", ",", ".", "`", " "}; private Bitmap rgbImage; private Boolean color = false; private int quality = 3; private int qualityColor = 6; private Spannable response; private Listener listener; public Img2Ascii(){ } public Img2Ascii bitmap(Bitmap rgbImage){ this.rgbImage = rgbImage; return this; } public Img2Ascii quality(int quality){ this.quality = quality; return this; } public Img2Ascii color(Boolean color){ this.color = color; return this; } public void convert(Listener listener) { this.listener = listener; new InstaApi().execute(); } @SuppressLint("StaticFieldLeak") private class InstaApi extends AsyncTask<String, Integer, Void> { private InstaApi(){ } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(String... arg0) { if(color) { quality = quality + qualityColor; if (quality > 5 + qualityColor || quality < 1 + qualityColor) quality = 3 + qualityColor; }else{ if (quality > 5 || quality < 1) quality = 3; } String tx; SpannableStringBuilder span = new SpannableStringBuilder(); int width = rgbImage.getWidth(); int height = rgbImage.getHeight(); int i = 0; for (int y = 0; y < height; y = y + quality) { for (int x = 0; x < width; x = x + quality) { int pixel = rgbImage.getPixel(x, y); int red = Color.red(pixel); int green = Color.green(pixel); int blue = Color.blue(pixel); if(color) { tx = "#"; span.append(tx); span.setSpan(new ForegroundColorSpan(Color.rgb(red, green, blue)), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); }else { int brightness = red + green + blue; brightness = round(brightness / (765 / (chars.length - 1))); tx = chars[brightness]; span.append(tx); } i++; } tx = "\n"; span.append(tx); publishProgress(y, height); i++; if(isCancelled()) break; } response = span; return null; } protected void onProgressUpdate(Integer... progress) { int current = progress[0]; int total = progress[1]; int percentage = 100 * current / total; listener.onProgress(percentage); } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); listener.onResponse(response); } } public interface Listener { void onProgress(int percentage); void onResponse(Spannable response); } }