Google Vision: Drawing mask on Face with animations - Android Apps and Games

I am using google vision library for face detection. Face detection is perfect and I get all the info like vertices, angles like eulerY, eulerZ.
I want to draw mask on face, drawing is ok but the face mask is not following the face position as it should, the position is not correct. Here is my edited code to draw face mask on googly eyes project.
Here is my source code:
package com.google.android.gms.samples.vision.face.googlyeyes;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.google.android.gms.samples.vision.face.googlyeyes.ui.camera.GraphicOverlay;
import com.google.android.gms.vision.face.Face;
import java.util.HashMap;
/**
* Graphics class for rendering Googly Eyes on a graphic overlay given the current eye positions.
*/
class GooglyEyesGraphic extends GraphicOverlay.Graphic {
private Paint mEyeWhitesPaint;
private Paint mEyeIrisPaint;
private Paint mEyeOutlinePaint;
private Paint mEyeLidPaint;
Paint mBoxPaint;
Context mContext;
private static final float BOX_STROKE_WIDTH = 20.0 f;
FrameLayout frameLayout;
ImageView imageView;
// Bitmap bmpOriginal;
//==============================================================================================
// Methods
//==============================================================================================
GooglyEyesGraphic(GraphicOverlay overlay, Context mContext) {
super(overlay);
this.mContext = mContext;
mEyeWhitesPaint = new Paint();
mEyeWhitesPaint.setColor(Color.WHITE);
mEyeWhitesPaint.setStyle(Paint.Style.FILL);
mEyeLidPaint = new Paint();
mEyeLidPaint.setColor(Color.YELLOW);
mEyeLidPaint.setStyle(Paint.Style.FILL);
mEyeIrisPaint = new Paint();
mEyeIrisPaint.setColor(Color.BLACK);
mEyeIrisPaint.setStyle(Paint.Style.FILL);
mEyeOutlinePaint = new Paint();
mEyeOutlinePaint.setColor(Color.BLACK);
mEyeOutlinePaint.setStyle(Paint.Style.STROKE);
mEyeOutlinePaint.setStrokeWidth(5);
mBoxPaint = new Paint();
mBoxPaint.setColor(Color.MAGENTA);
mBoxPaint.setStyle(Paint.Style.STROKE);
mBoxPaint.setStrokeWidth(BOX_STROKE_WIDTH);
mBoxPaint.setAlpha(40);
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = li.inflate(R.layout.mask_layout, null);
imageView = (ImageView) view.findViewById(R.id.flMaskIV);
frameLayout = (FrameLayout) view.findViewById(R.id.frameLayout);
}
private volatile Face mFace;
/**
* Updates the eye positions and state from the detection of the most recent frame. Invalidates
* the relevant portions of the overlay to trigger a redraw.
*/
void updateEyes(PointF leftPosition, boolean leftOpen,
PointF rightPosition, boolean rightOpen, Face mFace) {
if (facesList.containsKey(mFace.getId())) {
PointF pointF1 = facesList.get(mFace.getId()).getPosition();
PointF pointF2 = mFace.getPosition();
double x = Math.sqrt(Math.pow(pointF2.x - pointF1.x, 2) - Math.pow(pointF2.y - pointF1.y, 2));
if (x < 0)
x = (-1 * x);
if (x < 10)
return;
Log.e("face Called", "FaceCalled");
}
this.mFace = mFace;
facesList.put(mFace.getId(), mFace);
postInvalidate();
}
public HashMap < Integer, Face > facesList = new HashMap < > ();
/**
* Draws the current eye state to the supplied canvas. This will draw the eyes at the last
* reported position from the tracker, and the iris positions according to the physics
* simulations for each iris given motion and other forces.
*/
@override
public void draw(Canvas canvas) {
if (mFace == null)
return;
// if (facesList.containsKey(mFace.getId())) {
// PointF pointF1 = facesList.get(mFace.getId()).getPosition();
// PointF pointF2 = mFace.getPosition();
//
// double x = Math.sqrt(Math.pow(pointF2.x - pointF1.x, 2) - Math.pow(pointF2.y - pointF1.y, 2));
// if (x < 0)
// x = (-1 * x);
// if (x < 10)
// return;
// Log.e("face Called", "FaceCalled");
//
// }
//
// facesList.put(mFace.getId(), mFace);
if (this.canvas == null)
this.canvas = canvas;
applyMask();
}
Drawable drawable;
Canvas canvas;
private void applyMask() {
if (canvas == null)
return;
// Log.e("mFace.getEulerY()", "mFace.getEulerY()=> " + mFace.getEulerY());
if (GooglyEyesActivity.maskImgView != null) {
GooglyEyesActivity.maskImgView.setVisibility(View.GONE);
GooglyEyesActivity.maskImgView.setImageResource(GooglyEyesActivity.currEmoticonID);
}
float x = translateX(mFace.getPosition().x + mFace.getWidth() / 2);
float y = translateY(mFace.getPosition().y + mFace.getHeight() / 2);
// Draws a bounding box around the face.
float xOffset = scaleX(mFace.getWidth() / 2.0 f);
float yOffset = scaleY(mFace.getHeight() / 2.0 f);
float left = x - xOffset - 50;
float top = y - (yOffset) - 50;
float right = x + xOffset + 50;
float bottom = y + (yOffset) + 50;
// canvas.drawRect((int) left, (int) top, (int) right, (int) bottom, mBoxPaint);
drawable = GooglyEyesActivity.maskImgView.getDrawable();
///////////////////
canvas.save();
canvas.translate(left, top);
// frameLayout.setX(left);
// frameLayout.setY(top);
Rect rect = new Rect((int) left, (int) top, (int) right, (int) bottom);
frameLayout.measure(rect.width(), rect.height());
frameLayout.setLayoutParams(new LinearLayout.LayoutParams(rect.width(), rect.height()));
frameLayout.layout(0, 0, (int) right, (int) bottom);
frameLayout.setClipBounds(rect);
imageView.setLayoutParams(new FrameLayout.LayoutParams(rect.width(), rect.height()));
imageView.setRotationY(mFace.getEulerY());
imageView.setRotation(mFace.getEulerZ());
imageView.setImageDrawable(drawable);
frameLayout.draw(canvas);
canvas.restore();
}
}
Also i need to add animations so i tried using dlib library to get landmarks points and draw it using opengl but in opengl i dont have any function to populate the vertice array i am getting from dlib. As the dlib landmarks are in points but the array there is not in such a way. Any help will be appreciated for both scenarios.
Thank you in advance.
Thanks.

aijaz070110 said:
I am using google vision library for face detection. Face detection is perfect and I get all the info like vertices, angles like eulerY, eulerZ.
I want to draw mask on face, drawing is ok but the face mask is not following the face position as it should, the position is not correct. Here is my edited code to draw face mask on googly eyes project.
Here is my source code:
[...]
Also i need to add animations so i tried using dlib library to get landmarks points and draw it using opengl but in opengl i dont have any function to populate the vertice array i am getting from dlib. As the dlib landmarks are in points but the array there is not in such a way. Any help will be appreciated for both scenarios.
Thank you in advance.
Thanks.
Click to expand...
Click to collapse
Do you have any progress on this?

Related

[Q] Probably easy but...accelerometer and random generator

Trying to use a random image generator as an action if accelerometer is utilized....different image each time the phone is shook.
import java.util.Random;
import android.app.Activity;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;
public class ShakeActivity extends Activity implements SensorListener {
// For shake motion detection.
private SensorManager sensorMgr;
private long lastUpdate = -1;
private float x, y, z;
private float last_x, last_y, last_z;
private static final int SHAKE_THRESHOLD = 800;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// start motion detection
sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
boolean accelSupported = sensorMgr.registerListener(this,
SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_GAME);
if (!accelSupported) {
// on accelerometer on this device
sensorMgr.unregisterListener(this,
SensorManager.SENSOR_ACCELEROMETER);
}
}
protected void onPause() {
if (sensorMgr != null) {
sensorMgr.unregisterListener(this,
SensorManager.SENSOR_ACCELEROMETER);
sensorMgr = null;
}
super.onPause();
}
public void onAccuracyChanged(int arg0, int arg1) {
// TODO Auto-generated method stub
}
public void onSensorChanged(int sensor, float[] values) {
Log.d("sensor", "onSensorChanged: " + sensor);
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms.
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x = values[SensorManager.DATA_X];
y = values[SensorManager.DATA_Y];
z = values[SensorManager.DATA_Z];
float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;
// Log.d("sensor", "diff: " + diffTime + " - speed: " + speed);
if (speed > SHAKE_THRESHOLD) {
ImageView imgView = new ImageView(this);
Random rand = new Random();
int rndInt = rand.nextInt(4) + 1; // n = the number of images, that start at idx 1
String imgName = "img" + rndInt;
int id = getResources().getIdentifier(imgName, "drawable", getPackageName());
imgView.setImageResource(id);
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
}
Thanks in advance for help?

Cannot determine screen size in onDraw?

Hi!
I have written a test program that just draws a cross on the screen.
I have a webpage on a server with the hostname darkbox.dyndns.org. There is a directory called test on it. Now you can conclude the url to the directory where I have put the demonstration files for this question.
The TestActivity.java file shows how I try to draw the cross.
You can see different screenshots. When I try it on my phone, it seems that I dont have access to the full screen or something. Or how should I do this properly?
I got an error message when I tried to post the link. it reads like this:
"To prevent spam to the forums, ALL new users are not permitted to post outside links in their messages. After approximately eight posts, you will be able to post outside links. Thanks for understanding!"
Thats why I could not post the link
/best regards
purginator
The source
A bit easier if I give you the source instead of just giving you the url to it.
Here is comes (TestActivity.java).
package testing.testing;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TableLayout.LayoutParams;
public class TestActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags
(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new the_view(this));
}
private class the_view extends View
{
public the_view(Context context)
{
super(context);
setLayoutParams
(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
@Override
public void onDraw(Canvas canvas)
{
int width = canvas.getWidth();
int height = canvas.getHeight();
Paint paint = new Paint();
paint.setColor(0xffc0c0c0);
float[] points1 =
{
0, 0, width, 0,
width, 0, width, height,
width, height, 0, height,
0, height, 0, 0
};
float[] points2 = { 0,0, width, height };
float[] points3 = { width,0, 0, height };
paint.setStrokeWidth(10);
canvas.drawLines(points1, paint);
paint.setStrokeWidth(5);
canvas.drawLines(points2, paint);
canvas.drawLines(points3, paint);
}
}
}
I think size of the view can be determed wrong there:
Code:
int width = canvas.getWidth();
int height = canvas.getHeight();
Try to add this to your the_view class:
Code:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
invalidate();
}
It looks like your onDraw method is called only once with incorrect width and height because view doesn't still fill the parent layout. The code above will force it to redraw on any size change.
Does not work, the same behaviour
The idea is that you shouldn't use canvas size directly like this:
Code:
int width = canvas.getWidth();
int height = canvas.getHeight();
But should use view's size:
Code:
int width = getWidth();
int height = getHeight();
Solution found
All I had was to target a higher API version than 1.5.
I used 2.1 and I could use the whole screen.
So do never recommend people to use 1.5, as I was recommended!

[Q] Building Nyandroid + platlogo into an app

I've been hacking away at a few java files (PlatlogoActivity.java, Nyandroid.java) extracted from AOSP ICS source in Eclipse. There were some errors that I was able to solve (some funky ones about vibration, but I just removed all code related to vibration instead) but now there is one error, that no matter what, I can't solve. In the Nyandroid.java, I keep on getting the error "Cannot cast from TimeAnimator to ValueAnimator" on the line "((ValueAnimator) mAnim).cancel();" no matter how much I try changing that line (for example to "mAnim.cancel();") based on some custom ROM sources that I've looked through, and some stackoverflow questions. The app source is attached to this post, and below you can find the Nyandroid.java if you're willing to help - please do. I want to get into app developing for Android, or atleast understanding some java. I managed to port the Gingerbread platlogo for all Android versions but it's obviously much easier to do because it's just one still image and a toast. But I really want to port the ICS Nyandroid easter egg, for some practice with java.
/*);
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.nyandroid;
import android.animation.AnimatorSet;
import android.animation.PropertyValuesHolder;
import android.animation.ObjectAnimator;
import android.animation.TimeAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import java.util.HashMap;
import java.util.Random;
public class Nyandroid extends Activity {
final static boolean DEBUG = false;
public static class Board extends FrameLayout
{
public static final boolean FIXED_STARS = true;
public static final int NUM_CATS = 20;
static Random sRNG = new Random();
static float lerp(float a, float b, float f) {
return (b-a)*f + a;
}
static float randfrange(float a, float b) {
return lerp(a, b, sRNG.nextFloat());
}
static int randsign() {
return sRNG.nextBoolean() ? 1 : -1;
}
static <E> E pick(E[] array) {
if (array.length == 0) return null;
return array[sRNG.nextInt(array.length)];
}
public class FlyingCat extends ImageView {
public static final float VMAX = 1000.0f;
public static final float VMIN = 100.0f;
public float v, vr;
public float dist;
public float z;
public ComponentName component;
public FlyingCat(Context context, AttributeSet as) {
super(context, as);
setImageResource(R.drawable.nyandroid_anim); // @@@
if (DEBUG) setBackgroundColor(0x80FF0000);
}
public String toString() {
return String.format("<cat (%.1f, %.1f) (%d x %d)>",
getX(), getY(), getWidth(), getHeight());
}
public void reset() {
final float scale = lerp(0.1f,2f,z);
setScaleX(scale); setScaleY(scale);
setX(-scale*getWidth()+1);
setY(randfrange(0, Board.this.getHeight()-scale*getHeight()));
v = lerp(VMIN, VMAX, z);
dist = 0;
// android.util.Log.d("Nyandroid", "reset cat: " + this);
}
public void update(float dt) {
dist += v * dt;
setX(getX() + v * dt);
}
}
TimeAnimator mAnim;
public Board(Context context, AttributeSet as) {
super(context, as);
setLayerType(View.LAYER_TYPE_HARDWARE, null);
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
setBackgroundColor(0xFF003366);
}
private void reset() {
// android.util.Log.d("Nyandroid", "board reset");
removeAllViews();
final ViewGroup.LayoutParams wrap = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
if (FIXED_STARS) {
for(int i=0; i<20; i++) {
ImageView fixedStar = new ImageView(getContext(), null);
if (DEBUG) fixedStar.setBackgroundColor(0x8000FF80);
fixedStar.setImageResource(R.drawable.star_anim); // @@@
addView(fixedStar, wrap);
final float scale = randfrange(0.1f, 1f);
fixedStar.setScaleX(scale); fixedStar.setScaleY(scale);
fixedStar.setX(randfrange(0, getWidth()));
fixedStar.setY(randfrange(0, getHeight()));
final AnimationDrawable anim = (AnimationDrawable) fixedStar.getDrawable();
postDelayed(new Runnable() {
public void run() {
anim.start();
}}, (int) randfrange(0, 1000));
}
}
for(int i=0; i<NUM_CATS; i++) {
FlyingCat nv = new FlyingCat(getContext(), null);
addView(nv, wrap);
nv.z = ((float)i/NUM_CATS);
nv.z *= nv.z;
nv.reset();
nv.setX(randfrange(0,Board.this.getWidth()));
final AnimationDrawable anim = (AnimationDrawable) nv.getDrawable();
postDelayed(new Runnable() {
public void run() {
anim.start();
}}, (int) randfrange(0, 1000));
}
if (mAnim != null) {
((ValueAnimator) mAnim).cancel();
}
mAnim = new TimeAnimator();
mAnim.setTimeListener(new TimeAnimator.TimeListener() {
public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
// setRotation(totalTime * 0.01f); // not as cool as you would think
// android.util.Log.d("Nyandroid", "t=" + totalTime);
for (int i=0; i<getChildCount(); i++) {
View v = getChildAt(i);
if (!(v instanceof FlyingCat)) continue;
FlyingCat nv = (FlyingCat) v;
nv.update(deltaTime / 1000f);
final float catWidth = nv.getWidth() * nv.getScaleX();
final float catHeight = nv.getHeight() * nv.getScaleY();
if ( nv.getX() + catWidth < -2
|| nv.getX() > getWidth() + 2
|| nv.getY() + catHeight < -2
|| nv.getY() > getHeight() + 2)
{
nv.reset();
}
}
}
});
}
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh) {
super.onSizeChanged(w,h,oldw,oldh);
// android.util.Log.d("Nyandroid", "resized: " + w + "x" + h);
post(new Runnable() { public void run() {
reset();
mAnim.start();
} });
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAnim.cancel();
}
@Override
public boolean isOpaque() {
return true;
}
}
private Board mBoard;
@Override
public void onStart() {
super.onStart();
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
);
}
@Override
public void onResume() {
super.onResume();
mBoard = new Board(this, null);
setContentView(mBoard);
mBoard.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int vis) {
if (0 == (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) {
Nyandroid.this.finish();
}
}
});
}
@Override
public void onUserInteraction() {
// android.util.Log.d("Nyandroid", "finishing on user interaction");
finish();
}
}
Click to expand...
Click to collapse

[App] [Tutorial] Learn to make a Compass Application

Hello,
I create this post to present you a video tutorial showing you how to create a compass application for Android steps by steps. This tutorial lets beginners to start with sensors on Android and also to discover how to get GPS Location with default Android services.
Tutorial is here :
A demo application is also available on Google Play Store : https://play.google.com/store/apps/details?id=com.ssaurel.tinycompass
Don't hesitate to tell me if you want more details about the source code.
Sylvain
Compass View source code
Hello,
To start with source code, this is CompassView source code :
Code:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.ssaurel.tinycompass.R;
/**
* Compass view.
*
* @author Sylvain Saurel - [email protected]
*
*/
public class CompassView extends View {
private static final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int width = 0;
private int height = 0;
private Matrix matrix;
private Bitmap bitmap;
private float bearing;
public CompassView(Context context) {
super(context);
initialize();
}
public CompassView(Context context, AttributeSet attr) {
super(context, attr);
initialize();
}
private void initialize() {
matrix = new Matrix();
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.compass_icon);
}
public void setBearing(float bearing) {
this.bearing = bearing;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
int bitmapWidth = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
if (bitmap.getWidth() > canvasWidth || bitmap.getHeight() > canvasHeight) {
// resize to fit canvas
bitmap = Bitmap.createScaledBitmap(bitmap, (int) (bitmapWidth * .85), (int) (bitmapHeight * .85), true);
}
// calculate center position
int bitmapX = bitmap.getWidth() / 2;
int bitmapY = bitmap.getHeight() / 2;
int parentX = width / 2;
int parentY = height / 2;
int centerX = parentX - bitmapX;
int centerY = parentY - bitmapY;
// rotation angle
int rotation = (int) (360 - bearing);
// transformation matrix
matrix.reset();
// rotate on center to put on North
matrix.setRotate(rotation, bitmapX, bitmapY);
// translate bitmap to center
matrix.postTranslate(centerX, centerY);
// draw bitmap
canvas.drawBitmap(bitmap, matrix, paint);
}
}
Don't hesitate if you have comments .
Sylvain
Hello,
A blog article to complete the video tutorial is also available now : http://www.ssaurel.com/blog/learn-how-to-make-a-compass-application-for-android/
Sylvain

Memory Game inspired in Wordle

Hello everyone,
I just published a simple game but I think it has been very good. At least my kids love it.https://play.google.com/store/apps/details?id=com.ham.game.memo
I have mixed two concepts: the memory game of matching classic images with the wordle, that is, a daily game board and the possibility of sharing the result on Social Networks,
Download and comments are appreciated.
For anyone that could be interested this is the source code how i convert the drawable tiles to a image like wordle style:
public static Bitmap getImageMemo(Context context) {
// base
Drawable blank = null;
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
if(MemoColors.dark)
blank = App.context().getResources().getDrawable( R.drawable.keyback, App.context().getTheme());
else
blank = App.context().getResources().getDrawable( R.drawable.keyback_light, App.context().getTheme());
} else {
blank = ContextCompat.getDrawable(App.context(), R.drawable.keyback_light);
}
// create image
int margin = 2;
int piece = 48;
Bitmap image = Bitmap.createBitmap((int) piece * 5 + margin * 4, piece * 6 + margin * 5, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
int pTop = 0, pLeft = 0;
for(int row=1; row < 7; row++)
{
for(int col=1; col < 6; col++)
{
Drawable drawable = blank;
if(getActualWord(row, col) < 0)
drawable = MemoIcons.getIconByIndex(MemoIcons.getFamily("robots"), getIconToday(row, col));
drawable.setBounds(pLeft, pTop, pLeft+piece, pTop+piece);
drawable.draw(canvas);
pLeft += piece+margin;
}
pLeft = 0;
pTop += piece+margin;
}
return image;
}
seems very nicely designed.. will give it a try.. thx!

Categories

Resources