Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Adding More Images
  • Loading branch information
dragosholban committed Mar 8, 2018
1 parent abf3850 commit de6fe4f
Show file tree
Hide file tree
Showing 12 changed files with 472 additions and 209 deletions.
4 changes: 3 additions & 1 deletion app/src/main/AndroidManifest.xml
Expand Up @@ -9,14 +9,16 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PuzzleActivity"></activity>
</application>

</manifest>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
114 changes: 114 additions & 0 deletions app/src/main/java/dragosholban/com/androidpuzzlegame/ImageAdapter.java
@@ -0,0 +1,114 @@
package dragosholban.com.androidpuzzlegame;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import java.io.IOException;
import java.io.InputStream;

public class ImageAdapter extends BaseAdapter {
private Context mContext;
private AssetManager am;
private String[] files;

public ImageAdapter(Context c) {
mContext = c;
am = mContext.getAssets();
try {
files = am.list("img");
} catch (IOException e) {
e.printStackTrace();
}
}

public int getCount() {
return files.length;
}

public Object getItem(int position) {
return null;
}

public long getItemId(int position) {
return 0;
}

// create a new ImageView for each item referenced by the Adapter
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
convertView = layoutInflater.inflate(R.layout.grid_element, null);
}

final ImageView imageView = convertView.findViewById(R.id.gridImageview);
imageView.setImageBitmap(null);
// run image related code after the view was laid out
imageView.post(new Runnable() {
@Override
public void run() {
new AsyncTask<Void, Void, Void>() {
private Bitmap bitmap;
@Override
protected Void doInBackground(Void... voids) {
bitmap = getPicFromAsset(imageView, files[position]);
return null;
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
imageView.setImageBitmap(bitmap);
}
}.execute();
}
});

return convertView;
}

private Bitmap getPicFromAsset(ImageView imageView, String assetName) {
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();

if(targetW == 0 || targetH == 0) {
// view has no dimensions set
return null;
}

try {
InputStream is = am.open("img/" + assetName);
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;

// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

is.reset();

// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;

return BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
} catch (IOException e) {
e.printStackTrace();

return null;
}
}
}
213 changes: 22 additions & 191 deletions app/src/main/java/dragosholban/com/androidpuzzlegame/MainActivity.java
@@ -1,5 +1,7 @@
package dragosholban.com.androidpuzzlegame;

import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
Expand All @@ -12,212 +14,41 @@
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.io.IOException;
import java.util.ArrayList;

import static java.lang.Math.abs;

public class MainActivity extends AppCompatActivity {
ArrayList<PuzzlePiece> pieces;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

final RelativeLayout layout = findViewById(R.id.layout);
ImageView imageView = findViewById(R.id.imageView);

// run image related code after the view was laid out
// to have all dimensions calculated
imageView.post(new Runnable() {
@Override
public void run() {
pieces = splitImage();
TouchListener touchListener = new TouchListener();
for(PuzzlePiece piece : pieces) {
piece.setOnTouchListener(touchListener);
layout.addView(piece);
}
}
});
}

private ArrayList<PuzzlePiece> splitImage() {
int piecesNumber = 12;
int rows = 4;
int cols = 3;

ImageView imageView = findViewById(R.id.imageView);
ArrayList<PuzzlePiece> pieces = new ArrayList<>(piecesNumber);

// Get the scaled bitmap of the source image
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();

int[] dimensions = getBitmapPositionInsideImageView(imageView);
int scaledBitmapLeft = dimensions[0];
int scaledBitmapTop = dimensions[1];
int scaledBitmapWidth = dimensions[2];
int scaledBitmapHeight = dimensions[3];

int croppedImageWidth = scaledBitmapWidth - 2 * abs(scaledBitmapLeft);
int croppedImageHeight = scaledBitmapHeight - 2 * abs(scaledBitmapTop);

Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledBitmapWidth, scaledBitmapHeight, true);
Bitmap croppedBitmap = Bitmap.createBitmap(scaledBitmap, abs(scaledBitmapLeft), abs(scaledBitmapTop), croppedImageWidth, croppedImageHeight);

// Calculate the with and height of the pieces
int pieceWidth = croppedImageWidth/cols;
int pieceHeight = croppedImageHeight/rows;

// Create each bitmap piece and add it to the resulting array
int yCoord = 0;
for (int row = 0; row < rows; row++) {
int xCoord = 0;
for (int col = 0; col < cols; col++) {
// calculate offset for each piece
int offsetX = 0;
int offsetY = 0;
if (col > 0) {
offsetX = pieceWidth / 3;
AssetManager am = getAssets();
try {
final String[] files = am.list("img");

GridView grid = findViewById(R.id.grid);
grid.setAdapter(new ImageAdapter(this));
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(), PuzzleActivity.class);
intent.putExtra("assetName", files[i % files.length]);
startActivity(intent);
}
if (row > 0) {
offsetY = pieceHeight / 3;
}

// apply the offset to each piece
Bitmap pieceBitmap = Bitmap.createBitmap(croppedBitmap, xCoord - offsetX, yCoord - offsetY, pieceWidth + offsetX, pieceHeight + offsetY);
PuzzlePiece piece = new PuzzlePiece(getApplicationContext());
piece.setImageBitmap(pieceBitmap);
piece.xCoord = xCoord - offsetX + imageView.getLeft();
piece.yCoord = yCoord - offsetY + imageView.getTop();
piece.pieceWidth = pieceWidth + offsetX;
piece.pieceHeight = pieceHeight + offsetY;

// this bitmap will hold our final puzzle piece image
Bitmap puzzlePiece = Bitmap.createBitmap(pieceWidth + offsetX, pieceHeight + offsetY, Bitmap.Config.ARGB_8888);

// draw path
int bumpSize = pieceHeight / 4;
Canvas canvas = new Canvas(puzzlePiece);
Path path = new Path();
path.moveTo(offsetX, offsetY);
if (row == 0) {
// top side piece
path.lineTo(pieceBitmap.getWidth(), offsetY);
} else {
// top bump
path.lineTo(offsetX + (pieceBitmap.getWidth() - offsetX) / 3, offsetY);
path.cubicTo(offsetX + (pieceBitmap.getWidth() - offsetX) / 6, offsetY - bumpSize, offsetX + (pieceBitmap.getWidth() - offsetX) / 6 * 5, offsetY - bumpSize, offsetX + (pieceBitmap.getWidth() - offsetX) / 3 * 2, offsetY);
path.lineTo(pieceBitmap.getWidth(), offsetY);
}

if (col == cols - 1) {
// right side piece
path.lineTo(pieceBitmap.getWidth(), pieceBitmap.getHeight());
} else {
// right bump
path.lineTo(pieceBitmap.getWidth(), offsetY + (pieceBitmap.getHeight() - offsetY) / 3);
path.cubicTo(pieceBitmap.getWidth() - bumpSize,offsetY + (pieceBitmap.getHeight() - offsetY) / 6, pieceBitmap.getWidth() - bumpSize, offsetY + (pieceBitmap.getHeight() - offsetY) / 6 * 5, pieceBitmap.getWidth(), offsetY + (pieceBitmap.getHeight() - offsetY) / 3 * 2);
path.lineTo(pieceBitmap.getWidth(), pieceBitmap.getHeight());
}

if (row == rows - 1) {
// bottom side piece
path.lineTo(offsetX, pieceBitmap.getHeight());
} else {
// bottom bump
path.lineTo(offsetX + (pieceBitmap.getWidth() - offsetX) / 3 * 2, pieceBitmap.getHeight());
path.cubicTo(offsetX + (pieceBitmap.getWidth() - offsetX) / 6 * 5,pieceBitmap.getHeight() - bumpSize, offsetX + (pieceBitmap.getWidth() - offsetX) / 6, pieceBitmap.getHeight() - bumpSize, offsetX + (pieceBitmap.getWidth() - offsetX) / 3, pieceBitmap.getHeight());
path.lineTo(offsetX, pieceBitmap.getHeight());
}

if (col == 0) {
// left side piece
path.close();
} else {
// left bump
path.lineTo(offsetX, offsetY + (pieceBitmap.getHeight() - offsetY) / 3 * 2);
path.cubicTo(offsetX - bumpSize, offsetY + (pieceBitmap.getHeight() - offsetY) / 6 * 5, offsetX - bumpSize, offsetY + (pieceBitmap.getHeight() - offsetY) / 6, offsetX, offsetY + (pieceBitmap.getHeight() - offsetY) / 3);
path.close();
}

// mask the piece
Paint paint = new Paint();
paint.setColor(0XFF000000);
paint.setStyle(Paint.Style.FILL);

canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(pieceBitmap, 0, 0, paint);

// draw a white border
Paint border = new Paint();
border.setColor(0X80FFFFFF);
border.setStyle(Paint.Style.STROKE);
border.setStrokeWidth(8.0f);
canvas.drawPath(path, border);

// draw a black border
border = new Paint();
border.setColor(0X80000000);
border.setStyle(Paint.Style.STROKE);
border.setStrokeWidth(3.0f);
canvas.drawPath(path, border);

// set the resulting bitmap to the piece
piece.setImageBitmap(puzzlePiece);

pieces.add(piece);
xCoord += pieceWidth;
}
yCoord += pieceHeight;
});
} catch (IOException e) {
Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_SHORT);
}

return pieces;
}

private int[] getBitmapPositionInsideImageView(ImageView imageView) {
int[] ret = new int[4];

if (imageView == null || imageView.getDrawable() == null)
return ret;

// Get image dimensions
// Get image matrix values and place them in an array
float[] f = new float[9];
imageView.getImageMatrix().getValues(f);

// Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
final float scaleX = f[Matrix.MSCALE_X];
final float scaleY = f[Matrix.MSCALE_Y];

// Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
final Drawable d = imageView.getDrawable();
final int origW = d.getIntrinsicWidth();
final int origH = d.getIntrinsicHeight();

// Calculate the actual dimensions
final int actW = Math.round(origW * scaleX);
final int actH = Math.round(origH * scaleY);

ret[2] = actW;
ret[3] = actH;

// Get image position
// We assume that the image is centered into ImageView
int imgViewW = imageView.getWidth();
int imgViewH = imageView.getHeight();

int top = (int) (imgViewH - actH)/2;
int left = (int) (imgViewW - actW)/2;

ret[0] = left;
ret[1] = top;

return ret;
}
}

0 comments on commit de6fe4f

Please sign in to comment.