多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > 仿騰訊QQ拍照 背景圖片滑動獲取圖片

仿騰訊QQ拍照 背景圖片滑動獲取圖片

來源:程序員人生   發布時間:2015-07-28 07:52:39 閱讀次數:3274次

1.首先我們來看1下效果圖片



2.再看1下項目結構



3.里面注釋很多我就不仔細講了,大家仔細看吧

首先是MainActivity:

public class MainActivity extends Activity { private ClipImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = (ClipImageView) findViewById(R.id.src_pic); // 設置需要裁剪的圖片 imageView.setImageResource(R.drawable.test_pic); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if(item.getItemId() == R.id.action_clip){ // 此處獲得剪裁后的bitmap Bitmap bitmap = imageView.clip(); // 由于Intent傳遞bitmap不能超過40k,此處使用2進制數組傳遞 ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); byte[] bitmapByte = baos.toByteArray(); Intent intent = new Intent(this, PreviewActivity.class); intent.putExtra("bitmap", bitmapByte); startActivity(intent); } return super.onOptionsItemSelected(item); } }


再來看看:
PreviewActivity:

public class PreviewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.preview); setTitle("預覽"); ImageView imageView = (ImageView) findViewById(R.id.preview); byte[] bis = getIntent().getByteArrayExtra("bitmap"); Bitmap bitmap = BitmapFactory.decodeByteArray(bis, 0, bis.length); if(bitmap != null){ imageView.setImageBitmap(bitmap); } } }

自定義控件類:ClipImageView

public class ClipImageView extends ImageView implements View.OnTouchListener, ViewTreeObserver.OnGlobalLayoutListener{ private static final int BORDERDISTANCE = ClipView.BORDERDISTANCE; public static final float DEFAULT_MAX_SCALE = 4.0f; public static final float DEFAULT_MID_SCALE = 2.0f; public static final float DEFAULT_MIN_SCALE = 1.0f; private float minScale = DEFAULT_MIN_SCALE; private float midScale = DEFAULT_MID_SCALE; private float maxScale = DEFAULT_MAX_SCALE; private MultiGestureDetector multiGestureDetector; private int borderlength; private boolean isJusted; private final Matrix baseMatrix = new Matrix(); private final Matrix drawMatrix = new Matrix(); private final Matrix suppMatrix = new Matrix(); private final RectF displayRect = new RectF(); private final float[] matrixValues = new float[9]; public ClipImageView(Context context) { this(context, null); } public ClipImageView(Context context, AttributeSet attr) { this(context, attr, 0); } public ClipImageView(Context context, AttributeSet attr, int defStyle) { super(context, attr, defStyle); super.setScaleType(ScaleType.MATRIX); setOnTouchListener(this); multiGestureDetector = new MultiGestureDetector(context); } /** * 根據圖片寬高比例,設置圖象初始縮放等級和位置 */ private void configPosition(){ super.setScaleType(ScaleType.MATRIX); Drawable d = getDrawable(); if(d == null){ return; } final float viewWidth = getWidth(); final float viewHeight = getHeight(); final int drawableWidth = d.getIntrinsicWidth(); final int drawableHeight = d.getIntrinsicHeight(); borderlength = (int) (viewWidth - BORDERDISTANCE *2); float scale = 1.0f; /** * 判斷圖片寬高比例,調劑顯示位置和縮放大小 */ // 圖片寬度小于等于高度 if(drawableWidth <= drawableHeight){ // 判斷圖片寬度是不是小于邊框, 縮放鋪滿裁剪邊框 if(drawableWidth < borderlength){ baseMatrix.reset(); scale = (float)borderlength / drawableWidth; // 縮放 baseMatrix.postScale(scale, scale); } // 圖片寬度大于高度 }else{ if(drawableHeight < borderlength){ baseMatrix.reset(); scale = (float)borderlength / drawableHeight; // 縮放 baseMatrix.postScale(scale, scale); } } // 移動居中 baseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2, (viewHeight - drawableHeight * scale)/2); resetMatrix(); isJusted = true; } @Override public boolean onTouch(View v, MotionEvent event) { return multiGestureDetector.onTouchEvent(event); } private class MultiGestureDetector extends GestureDetector.SimpleOnGestureListener implements OnScaleGestureListener { private final ScaleGestureDetector scaleGestureDetector; private final GestureDetector gestureDetector; private final float scaledTouchSlop; private VelocityTracker velocityTracker; private boolean isDragging; private float lastTouchX; private float lastTouchY; private float lastPointerCount; public MultiGestureDetector(Context context) { scaleGestureDetector = new ScaleGestureDetector(context, this); gestureDetector = new GestureDetector(context, this); gestureDetector.setOnDoubleTapListener(this); final ViewConfiguration configuration = ViewConfiguration.get(context); scaledTouchSlop = configuration.getScaledTouchSlop(); } @Override public boolean onScale(ScaleGestureDetector detector) { float scale = getScale(); float scaleFactor = detector.getScaleFactor(); if(getDrawable() != null && ((scale < maxScale && scaleFactor > 1.0f) || (scale > minScale && scaleFactor < 1.0f))){ if(scaleFactor * scale < minScale){ scaleFactor = minScale / scale; } if(scaleFactor * scale > maxScale){ scaleFactor = maxScale / scale; } suppMatrix.postScale(scaleFactor, scaleFactor, getWidth()/2, getHeight()/2); checkAndDisplayMatrix(); } return true; } @Override public boolean onScaleBegin(ScaleGestureDetector detector) { return true; } @Override public void onScaleEnd(ScaleGestureDetector detector) { } public boolean onTouchEvent(MotionEvent event) { if (gestureDetector.onTouchEvent(event)) { return true; } scaleGestureDetector.onTouchEvent(event); /* * Get the center x, y of all the pointers */ float x = 0, y = 0; final int pointerCount = event.getPointerCount(); for (int i = 0; i < pointerCount; i++) { x += event.getX(i); y += event.getY(i); } x = x / pointerCount; y = y / pointerCount; /* * If the pointer count has changed cancel the drag */ if (pointerCount != lastPointerCount) { isDragging = false; if (velocityTracker != null) { velocityTracker.clear(); } lastTouchX = x; lastTouchY = y; } lastPointerCount = pointerCount; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (velocityTracker == null) { velocityTracker = VelocityTracker.obtain(); } else { velocityTracker.clear(); } velocityTracker.addMovement(event); lastTouchX = x; lastTouchY = y; isDragging = false; break; case MotionEvent.ACTION_MOVE: { final float dx = x - lastTouchX, dy = y - lastTouchY; if (isDragging == false) { // Use Pythagoras to see if drag length is larger than // touch slop isDragging = Math.sqrt((dx * dx) + (dy * dy)) >= scaledTouchSlop; } if (isDragging) { if (getDrawable() != null) { suppMatrix.postTranslate(dx, dy); checkAndDisplayMatrix(); } lastTouchX = x; lastTouchY = y; if (velocityTracker != null) { velocityTracker.addMovement(event); } } break; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: lastPointerCount = 0; if (velocityTracker != null) { velocityTracker.recycle(); velocityTracker = null; } break; } return true; } @Override public boolean onDoubleTap(MotionEvent event) { try { float scale = getScale(); float x = getWidth() / 2; float y = getHeight() / 2; if (scale < midScale) { post(new AnimatedZoomRunnable(scale, midScale, x, y)); } else if ((scale >= midScale) && (scale < maxScale)) { post(new AnimatedZoomRunnable(scale, maxScale, x, y)); } else { post(new AnimatedZoomRunnable(scale, minScale, x, y)); } } catch (Exception e) { // Can sometimes happen when getX() and getY() is called } return true; } } private class AnimatedZoomRunnable implements Runnable { // These are 'postScale' values, means they're compounded each iteration static final float ANIMATION_SCALE_PER_ITERATION_IN = 1.07f; static final float ANIMATION_SCALE_PER_ITERATION_OUT = 0.93f; private final float focalX, focalY; private final float targetZoom; private final float deltaScale; public AnimatedZoomRunnable(final float currentZoom, final float targetZoom, final float focalX, final float focalY) { this.targetZoom = targetZoom; this.focalX = focalX; this.focalY = focalY; if (currentZoom < targetZoom) { deltaScale = ANIMATION_SCALE_PER_ITERATION_IN; } else { deltaScale = ANIMATION_SCALE_PER_ITERATION_OUT; } } public void run() { suppMatrix.postScale(deltaScale, deltaScale, focalX, focalY); checkAndDisplayMatrix(); final float currentScale = getScale(); if (((deltaScale > 1f) && (currentScale < targetZoom)) || ((deltaScale < 1f) && (targetZoom < currentScale))) { // We haven't hit our target scale yet, so post ourselves // again postOnAnimation(ClipImageView.this, this); } else { // We've scaled past our target zoom, so calculate the // necessary scale so we're back at target zoom final float delta = targetZoom / currentScale; suppMatrix.postScale(delta, delta, focalX, focalY); checkAndDisplayMatrix(); } } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void postOnAnimation(View view, Runnable runnable) { if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { view.postOnAnimation(runnable); } else { view.postDelayed(runnable, 16); } } /** * Returns the current scale value * * @return float - current scale value */ public final float getScale() { suppMatrix.getValues(matrixValues); return matrixValues[Matrix.MSCALE_X]; } @Override public void onGlobalLayout() { if(isJusted){ return; } // 調劑視圖位置 configPosition(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnGlobalLayoutListener(this); } @SuppressWarnings("deprecation") @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); getViewTreeObserver().removeGlobalOnLayoutListener(this); } /** * Helper method that simply checks the Matrix, and then displays the result */ private void checkAndDisplayMatrix() { checkMatrixBounds(); setImageMatrix(getDisplayMatrix()); } private void checkMatrixBounds() { final RectF rect = getDisplayRect(getDisplayMatrix()); if (null == rect) { return; } float deltaX = 0, deltaY = 0; final float viewWidth = getWidth(); final float viewHeight = getHeight(); // 判斷移動或縮放后,圖片顯示是不是超越裁剪框邊界 if(rect.top > (viewHeight - borderlength) / 2){ deltaY = (viewHeight - borderlength) / 2 - rect.top; } if(rect.bottom < (viewHeight + borderlength) / 2){ deltaY = (viewHeight + borderlength) / 2 - rect.bottom; } if(rect.left > (viewWidth - borderlength) / 2){ deltaX = (viewWidth - borderlength) / 2 - rect.left; } if(rect.right < (viewWidth + borderlength) / 2){ deltaX = (viewWidth + borderlength) / 2 - rect.right; } // Finally actually translate the matrix suppMatrix.postTranslate(deltaX, deltaY); } /** * Helper method that maps the supplied Matrix to the current Drawable * * @param matrix * - Matrix to map Drawable against * @return RectF - Displayed Rectangle */ private RectF getDisplayRect(Matrix matrix) { Drawable d = getDrawable(); if (null != d) { displayRect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); matrix.mapRect(displayRect); return displayRect; } return null; } /** * Resets the Matrix back to FIT_CENTER, and then displays it.s */ private void resetMatrix() { if(suppMatrix == null){ return; } suppMatrix.reset(); setImageMatrix(getDisplayMatrix()); } protected Matrix getDisplayMatrix() { drawMatrix.set(baseMatrix); drawMatrix.postConcat(suppMatrix); return drawMatrix; } /** * 剪切圖片,返回剪切后的bitmap對象 * * @return */ public Bitmap clip(){ Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); draw(canvas); return Bitmap.createBitmap(bitmap, (getWidth() - borderlength) / 2, (getHeight() - borderlength) / 2, borderlength, borderlength); } }

ClipView類

/** * 裁剪邊框 * * @author king * @time 2014⑹⑴8 下午3:53:00 */ public class ClipView extends View { /** * 邊框距左右側界距離,用于調劑邊框長度 */ public static final int BORDERDISTANCE = 50; private Paint mPaint; public ClipView(Context context) { this(context, null); } public ClipView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ClipView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = this.getWidth(); int height = this.getHeight(); // 邊框長度,據屏幕左右側緣50px int borderlength = width - BORDERDISTANCE *2; mPaint.setColor(0xaa000000); // 以下繪制透明暗色區域 // top canvas.drawRect(0, 0, width, (height - borderlength) / 2, mPaint); // bottom canvas.drawRect(0, (height + borderlength) / 2, width, height, mPaint); // left canvas.drawRect(0, (height - borderlength) / 2, BORDERDISTANCE, (height + borderlength) / 2, mPaint); // right canvas.drawRect(borderlength + BORDERDISTANCE, (height - borderlength) / 2, width, (height + borderlength) / 2, mPaint); // 以下繪制邊框線 mPaint.setColor(Color.WHITE); mPaint.setStrokeWidth(2.0f); // top canvas.drawLine(BORDERDISTANCE, (height - borderlength) / 2, width - BORDERDISTANCE, (height - borderlength) / 2, mPaint); // bottom canvas.drawLine(BORDERDISTANCE, (height + borderlength) / 2, width - BORDERDISTANCE, (height + borderlength) / 2, mPaint); // left canvas.drawLine(BORDERDISTANCE, (height - borderlength) / 2, BORDERDISTANCE, (height + borderlength) / 2, mPaint); // right canvas.drawLine(width - BORDERDISTANCE, (height - borderlength) / 2, width - BORDERDISTANCE, (height + borderlength) / 2, mPaint); }

下面貼1下xml:

activiti_main:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/black" tools:context=".MainActivity" > <com.example.test.widget.ClipImageView android:id="@+id/src_pic" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <com.example.test.widget.ClipView android:id="@+id/clipview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout>

preview.xml:

<?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" android:background="@android:color/black" > <ImageView android:id="@+id/preview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/app_name" /> </LinearLayout>

主要的代碼就是這些:

下面看1下最后的效果圖:



需要源碼的可以給我留言,或加QQ群

    96843339    我會及時給你回復。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 亚洲欧洲一区二区三区 | 欧美日韩你懂的 | 婷婷在线五月 | 日本视频在线观看不卡高清免费 | 色聚网久久综合 | 中文字幕成人 | 国产欧美日韩在线一区二区不卡 | 欧美一区二区三区在线观看不卡 | 亚洲国产精品综合欧美 | 精品无人乱码一区二区三区 | 成人欧美在线 | 手机看片精品高清国产日韩 | 伊人网五月天 | 亚洲免费精品视频 | 午夜色视频在线观看 | 玖玖国产精品视频 | 亚洲www| 欧美成人网在线综合视频 | 私人午夜影院 | 在线亚洲小视频 | 精品国产免费人成在线观看 | 偷窥自拍校园春色 | 欧美一级h| 国产一级淫片a免费播放口欧美 | 嫩草影院在线观看精品 | 日韩欧美手机在线 | 欧美另类videosbestsex高清 | 91精品国产福利在线观看 | 中文字幕资源在线 | 五月婷婷伊人 | 五月天基地 | 九九精品视频一区二区三区 | 日韩欧美一区二区在线观看 | 一区二区不卡在线 | 大香伊蕉在人线国产75视频 | 亚洲免费小视频 | 国产二三区 | 偷自视频区视频真实在线 | 最近中文在线中文 | 久久精品视 | 国产成人一区二区三区视频免费 |