import android.Manifest; import android.annotation.SuppressLint; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.media.MediaScannerConnection; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.InputFilter; import android.text.TextWatcher; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.FileOutputStream; import java.util.Locale; import java.util.Random; public class ComposeImageActivity extends AppCompatActivity { private EditText etSrc; private TextView tvCounter; private int MAX_INPUT_LENGTH; private static final int REQ_STORAGE_PERMS = 1000; @SuppressLint("SetTextI18n") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_compose_image); int dim = PreferenceUtils.getImagePrefs(this)[2]; MAX_INPUT_LENGTH = (dim * dim) - getString(R.string.validation_key).length(); if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); } etSrc = findViewById(R.id.et_src); Button btnCreateImage = findViewById(R.id.btn_build_image); tvCounter = findViewById(R.id.tv_char_counter); etSrc.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_INPUT_LENGTH)}); tvCounter.setText(String.format(Locale.getDefault(), "0/%d", MAX_INPUT_LENGTH)); etSrc.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { tvCounter.setText(String.format(Locale.getDefault(), "%d/%d", etSrc.getText().toString().length(), MAX_INPUT_LENGTH)); } @Override public void afterTextChanged(Editable editable) { } }); btnCreateImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String text = etSrc.getText().toString().trim(); if (text.length() > 0) { int extStorage = ContextCompat.checkSelfPermission(ComposeImageActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (extStorage != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(ComposeImageActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQ_STORAGE_PERMS); } else { init(); } } } }); } private void saveImage(Bitmap bitmap) { String root = Environment.getExternalStorageDirectory().toString(); File myDir = new File(root + "/ImageMessage"); if (!myDir.exists()) { myDir.mkdirs(); } String fileName = "image-message-generated-" + System.currentTimeMillis() + ".jpg"; File file = new File(myDir, fileName); try { FileOutputStream out = new FileOutputStream(file); if (bitmap != null) { bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); } out.flush(); out.close(); MediaScannerConnection.scanFile(this, new String[]{file.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() { public void onScanCompleted(String path, Uri uri) { Log.i("ExternalStorage", "Scanned " + path + ":"); Log.i("ExternalStorage", "-> uri=" + uri); } }); msg("Image Saved"); } catch (Exception e) { e.printStackTrace(); msg(e.getMessage()); } } private void msg(String s) { Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show(); } private void displayPreviewDialog(String str) { final AlertDialog builder = new AlertDialog.Builder(ComposeImageActivity.this).create(); View v = LayoutInflater.from(ComposeImageActivity.this).inflate(R.layout.img_preview_dialog, null); builder.setView(v); final ImageView img = v.findViewById(R.id.dialog_image_view); Button btnSave = v.findViewById(R.id.btn_dialog_save); Button btnCancel = v.findViewById(R.id.btn_dialog_cancel); TextView tvDims = v.findViewById(R.id.tv_dims); builder.setCanceledOnTouchOutside(false); int c = 0; Random random = new Random(); int [] vals = PreferenceUtils.getImagePrefs(ComposeImageActivity.this); int red = vals[0],green = vals[1],delimiter = 0, dims = vals[2]; tvDims.setText(String.format(Locale.getDefault(), "%dpx x %dpx", dims, dims)); Bitmap image = Bitmap.createBitmap(dims, dims, Bitmap.Config.ARGB_8888); for (int i = 0; i < dims; i++) { for (int j = 0; j < dims; j++) { if (c < str.length()) { image.setPixel(j, i, Color.rgb(random.nextInt(red)+1, random.nextInt(green)+1, (int) str.charAt(c))); } else if (c == str.length()) { image.setPixel(j, i, Color.rgb(delimiter, delimiter, delimiter)); } else { image.setPixel(j, i, Color.rgb(random.nextInt(red)+1, random.nextInt(green)+1, random.nextInt(127) + 1)); } c++; } } img.setImageBitmap(image); btnSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { BitmapDrawable bmd = (BitmapDrawable) img.getDrawable(); Bitmap bitmap = bmd.getBitmap(); saveImage(bitmap); builder.dismiss(); } }); btnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { builder.dismiss(); } }); builder.show(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQ_STORAGE_PERMS: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { init(); } break; } } private void init() { String text = etSrc.getText().toString().trim(); text = getString(R.string.validation_key).concat(text); displayPreviewDialog(text); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_compose, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_paste) { paste(); return true; } if (id == R.id.action_clear) { etSrc.setText(""); return true; } if (id == android.R.id.home) { finish(); return true; } return super.onOptionsItemSelected(item); } private void paste() { ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); if (clipboard == null) return; ClipData clip = clipboard.getPrimaryClip(); if (clip == null) return; ClipData.Item item = clip.getItemAt(0); if (item == null) return; CharSequence textToPaste = item.getText(); if (textToPaste != null && textToPaste.length() > 0) etSrc.setText(String.valueOf(textToPaste)); } }