Created
September 1, 2010 14:50
-
-
Save vvakame/560780 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="net.vvakame.polkodotter" android:versionCode="1" | |
android:versionName="1.0"> | |
<uses-sdk android:minSdkVersion="7" /> | |
<application android:icon="@drawable/icon" android:label="@string/app_name" | |
android:name=".MyApplication" android:debuggable="true"> | |
<activity android:name=".MainActivity" android:label="@string/app_name"> | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN" /> | |
<category android:name="android.intent.category.LAUNCHER" /> | |
</intent-filter> | |
</activity> | |
<activity android:name=".DotActivity" android:label="@string/app_name" | |
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" | |
android:configChanges="keyboardHidden|orientation"> | |
</activity> | |
</application> | |
<uses-permission android:name="android.permission.CAMERA" /> | |
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.vvakame.polkodotter; | |
import java.io.InputStream; | |
import roboguice.inject.InjectExtra; | |
import android.app.Activity; | |
import android.content.ContentResolver; | |
import android.graphics.Bitmap; | |
import android.graphics.BitmapFactory; | |
import android.net.Uri; | |
import android.util.DisplayMetrics; | |
import com.google.inject.Inject; | |
import com.google.inject.Provider; | |
public class BitmapFromUriExtraProvider implements Provider<Bitmap> { | |
@Inject | |
protected Activity act; | |
@InjectExtra("mediaImageUri") | |
protected Uri mediaUri; | |
@Override | |
public Bitmap get() { | |
ContentResolver resolver = act.getContentResolver(); | |
Bitmap bitmap = null; | |
if (mediaUri != null) { | |
try { | |
BitmapFactory.Options options = new BitmapFactory.Options(); | |
options.inJustDecodeBounds = true; | |
InputStream is = resolver.openInputStream(mediaUri); | |
BitmapFactory.decodeStream(is, null, options); | |
DisplayMetrics metrics = new DisplayMetrics(); | |
act.getWindowManager().getDefaultDisplay().getMetrics(metrics); | |
// 端末にあわせるため、幅が広い方を高さ、狭い方を幅とする。後の事は渡した先でやってくれ | |
final int width; | |
final int height; | |
if (options.outWidth < options.outHeight) { | |
width = options.outWidth; | |
height = options.outHeight; | |
} else { | |
width = options.outHeight; | |
height = options.outWidth; | |
} | |
if (metrics.widthPixels * 2 < width | |
|| metrics.heightPixels * 2 < height) { | |
// 端末解像度 〜 端末解像度 * 2 の範囲に収まるサイズにする | |
int scaleW = width / metrics.widthPixels; | |
int scaleH = height / metrics.heightPixels; | |
options.inSampleSize = Math.max(scaleW, scaleH); | |
} | |
is = resolver.openInputStream(mediaUri); | |
options.inJustDecodeBounds = false; | |
// NativeHeapから確保 | |
// https://twitter.com/shoozhoo/statuses/22621375376 | |
BitmapFactory.Options.class.getField("inNativeAlloc") | |
.setBoolean(options, true); | |
bitmap = BitmapFactory.decodeStream(is, null, options); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
return bitmap; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/frame" android:orientation="vertical" | |
android:layout_width="fill_parent" android:layout_height="fill_parent" | |
android:gravity="center_vertical|center_horizontal"> | |
<ImageView android:id="@+id/baseImage" android:layout_width="wrap_content" | |
android:layout_height="wrap_content" /> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.vvakame.polkodotter; | |
import java.util.ArrayList; | |
import java.util.List; | |
import roboguice.activity.GuiceActivity; | |
import roboguice.inject.InjectView; | |
import android.app.Activity; | |
import android.graphics.Bitmap; | |
import android.graphics.Canvas; | |
import android.graphics.Color; | |
import android.graphics.Paint; | |
import android.graphics.PointF; | |
import android.graphics.drawable.BitmapDrawable; | |
import android.media.FaceDetector; | |
import android.media.FaceDetector.Face; | |
import android.os.Bundle; | |
import android.widget.ImageView; | |
import android.widget.LinearLayout; | |
import com.google.inject.Inject; | |
public class DotActivity extends GuiceActivity { | |
@SuppressWarnings("unused") | |
private final Activity self = this; | |
private List<CircleF> circleList = new ArrayList<CircleF>(); | |
private boolean first = true; | |
// Powered by BitmapFromUriExtraProvider | |
@Inject | |
private Bitmap mBGBitmap; | |
private Bitmap mBGThumb; | |
private Bitmap mClipBitmap; | |
private Canvas mCanvas; | |
private Paint mPaint; | |
@InjectView(R.id.frame) | |
LinearLayout mFrame; | |
@InjectView(R.id.baseImage) | |
ImageView mBaseImage; | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.dot); // Injection now!! | |
mBaseImage.setBackgroundDrawable(new BitmapDrawable(mBGBitmap)); | |
} | |
@Override | |
public void onWindowFocusChanged(boolean hasFocus) { | |
super.onWindowFocusChanged(hasFocus); | |
if (!first) { | |
return; | |
} | |
final int height; | |
final int width; | |
if (mFrame.getWidth() < mBGBitmap.getWidth() | |
&& mFrame.getHeight() < mBGBitmap.getHeight()) { | |
width = mFrame.getWidth(); | |
height = mFrame.getHeight(); | |
mBGThumb = Bitmap | |
.createScaledBitmap(mBGBitmap, width, height, true); | |
} else { | |
width = mBGBitmap.getWidth(); | |
height = mBGBitmap.getHeight(); | |
mBGThumb = mBGBitmap; | |
} | |
Face[] faces = new Face[1]; | |
FaceDetector detector = new FaceDetector(width, height, faces.length); | |
int num = detector.findFaces(mBGThumb, faces); | |
for (int i = 0; i < num; i++) { | |
Face face = faces[i]; | |
PointF point = new PointF(); | |
face.getMidPoint(point); | |
float eyesDistance = face.eyesDistance(); | |
// 美人顔の人の比率 目と目の間の長さ = 鼻の幅, 鼻の幅 * 4 = 顔の横幅 | |
// 顔の横幅 * 1.5 = 顔の高さ ↓でもこのMagicNumberは適当に決めた | |
circleList.add(new CircleF(point.x, point.y, | |
(float) (eyesDistance * 1.7))); | |
} | |
final Bitmap.Config c = Bitmap.Config.ARGB_8888; | |
// Clip | |
mClipBitmap = Bitmap.createBitmap(width, height, c); | |
mCanvas = new Canvas(); | |
mCanvas.setBitmap(mClipBitmap); | |
mPaint = new Paint(); | |
mPaint.setColor(Color.argb(255, 255, 255, 255)); | |
mPaint.setAntiAlias(true); | |
for (CircleF circle : circleList) { | |
mCanvas.drawCircle(circle.cx, circle.cy, circle.radius, mPaint); | |
} | |
// 前景の作成 | |
final int color = Color.argb(0, 120, 255, 255); | |
int[] pixels = new int[width * height]; | |
mClipBitmap.getPixels(pixels, 0, width, 0, 0, width, height); | |
final int length = pixels.length; | |
for (int i = 0; i < length; i++) { | |
// ^ 0xff000000 Alphaの反転 | |
// & 0xff000000 Alpha以外の切り捨て | |
// | color Alpha以外の値の設定 | |
pixels[i] = pixels[i] ^ 0xff000000 & 0xff000000 | color; | |
} | |
mClipBitmap.setPixels(pixels, 0, width, 0, 0, width, height); | |
mBaseImage.setImageBitmap(mClipBitmap); | |
first = false; | |
} | |
class CircleF { | |
float cx; | |
float cy; | |
float radius; | |
public CircleF(float cx, float cy, float radius) { | |
this.cx = cx; | |
this.cy = cy; | |
this.radius = radius; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:orientation="vertical" android:layout_width="fill_parent" | |
android:layout_height="fill_parent" android:gravity="center_vertical|center_horizontal"> | |
<ImageButton android:id="@+id/gallery" android:src="@android:drawable/ic_menu_gallery" | |
android:layout_width="wrap_content" android:layout_height="wrap_content" /> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.vvakame.polkodotter; | |
import roboguice.activity.GuiceActivity; | |
import roboguice.inject.InjectView; | |
import android.app.Activity; | |
import android.content.Intent; | |
import android.net.Uri; | |
import android.os.Bundle; | |
import android.view.View; | |
import android.view.View.OnClickListener; | |
import android.widget.ImageButton; | |
public class MainActivity extends GuiceActivity { | |
@SuppressWarnings("unused") | |
private final Activity self = this; | |
private final int REQUEST_PICK_CONTACT = 0; | |
@InjectView(R.id.gallery) | |
ImageButton mButton; | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.main); // Injection now!! | |
mButton.setOnClickListener(new OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
Intent intent = new Intent(Intent.ACTION_PICK); | |
intent.setType("image/*"); | |
startActivityForResult(intent, REQUEST_PICK_CONTACT); | |
} | |
}); | |
} | |
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
super.onActivityResult(requestCode, resultCode, data); | |
if (requestCode == REQUEST_PICK_CONTACT) { | |
data.setClass(this, DotActivity.class); | |
Uri pictUri = data.getData(); | |
if (pictUri != null) { | |
data.putExtra("mediaImageUri", pictUri); | |
startActivity(data); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.vvakame.polkodotter; | |
import java.util.List; | |
import com.google.inject.Module; | |
import roboguice.application.GuiceApplication; | |
public class MyApplication extends GuiceApplication { | |
protected void addApplicationModules(List<Module> modules) { | |
modules.add(new MyModule()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.vvakame.polkodotter; | |
import android.graphics.Bitmap; | |
import roboguice.config.AbstractAndroidModule; | |
public class MyModule extends AbstractAndroidModule { | |
@Override | |
protected void configure() { | |
bind(Bitmap.class).toProvider(BitmapFromUriExtraProvider.class); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment