編輯:關於android開發
一般白色就是0,黑色就是1
單色位圖:
8位表示一個字節,
大小:長*寬/8,表示大小,還有一些文件信息如創建時間,什麼工具創建之類的
24位位圖
一個像素表示24位
大小:長*寬*24/8
256色
1個像素可以表示256種顏色 一個字節它的長度剛好是256 ,那麼一個像素點就是一個字節
大小:長*寬
安卓中默認使用32位的
將一個圖片放在SD卡上,使用BitmapFactory.decodeFile解析得Bitmap設置ImageView顯示
ImageView iv = (ImageView) findViewById(R.id.iv); //加載圖片 //Bitmap bitmap =BitmapFactory.decodeFile("/mnt/sdcard/img7.jpg"); Bitmap bitmap =BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/img7.jpg"); //設置圖片 iv.setImageBitmap(bitmap);
以上的圖片可以正常加載
異常現象---加載 的圖片過大,如2560*1520之類的,加載 時就會報OutMemoryError內存溢出
java.lang.OutOfMemoryError
獲取屏幕的大小寬和高
//1. 獲取到屏幕分辨率 WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE); Display display = manager.getDefaultDisplay(); Point outSize = new Point(); display.getSize(outSize); int x = outSize.x;
使用圖片的大小寬和屏幕的寬相除,圖片的高與屏幕的高相除,比大小,取最大值,或者取中間值
/** 圖片設置縮放比例 @author 劉楠 * 2016-3-3下午1:20:28 */ @SuppressLint("NewApi") public class MainActivity extends Activity { private static final String TAG = "MainActivity"; /* * 源圖片 */ private ImageView src; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 源圖片 src = (ImageView) findViewById(R.id.src); /*Options options = new Options(); options.inJustDecodeBounds=true; BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/2.jpg",options);*/ /** * 得到屏幕的寬高 */ WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE); Display defaultDisplay = manager.getDefaultDisplay(); Point point = new Point(); defaultDisplay.getRealSize(point); int screenWidth = point.x; int screenHeight = point.y; Log.d(TAG, "屏幕寬:"+screenWidth); Log.d(TAG, "屏幕高:"+screenHeight); /* * jpg圖片解析 */ try { ExifInterface jpgExifInterface = new ExifInterface( Environment.getExternalStorageDirectory() + "/2.jpg"); /* * 圖片的寬度 */ String width = jpgExifInterface .getAttribute(ExifInterface.TAG_IMAGE_WIDTH); /* * 得到圖片的高度 */ String height = jpgExifInterface .getAttribute(ExifInterface.TAG_IMAGE_LENGTH); Log.d(TAG, "圖片寬:"+width); Log.d(TAG, "圖片高:"+height); //計算比例 int scale=Integer.parseInt(width)/screenWidth>Integer.parseInt(height)/screenHeight?Integer.parseInt(width)/screenWidth:Integer.parseInt(height)/screenHeight; //設置顯示 Log.d(TAG,"比例:"+scale); //調置采樣率,比例 Options opts = new Options(); opts.inSampleSize=scale; //使用工廠再次解析 Bitmap decodeFile = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/2.jpg", opts); //設置圖片顯示 src.setImageBitmap(decodeFile); } catch (IOException e) { e.printStackTrace(); } }
只需要更改Matrix
Matrix matrix = new Matrix();
//移動第一個參數x 水平, 第二個參數y高度,可以是負值
/*
* degrees角度:
* px:開始旋轉的水平坐標
* py:開始旋轉的垂直坐標
*/
matrix.setRotate(90, bitmap.getWidth()/2, bitmap.getHeight()/2);
前者是在原圖基礎上做變化,後者是在目前的效果基礎上做變化
布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layoutwidth="matchparent" android:layoutheight="matchparent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="15dp" android:orientation="horizontal" > <!-- 畫筆顏色 --> <View android:id="@+id/red" android:layout_width="50dp" android:layout_height="50dp" android:background="#ff0000" /> <View android:id="@+id/green" android:layout_width="50dp" android:layout_height="50dp" android:background="#00ff00" /> <View android:id="@+id/blue" android:layout_width="50dp" android:layout_height="50dp" android:background="#0000ff" /> <View android:id="@+id/yellow" android:layout_width="50dp" android:layout_height="50dp" android:background="#ffff00" /> <View android:id="@+id/purple" android:layout_width="50dp" android:layout_height="50dp" android:background="#ff00ff" /> </LinearLayout> <!-- 畫筆粗細 --> <SeekBar android:id="@+id/seekbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="20" android:progress="5" android:thumb="@drawable/ok" /> <!-- 塗鴉的地方 --> <ImageView android:id="@+id/iv_result" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
菜單R.menu.main
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/save" android:orderInCategory="100" android:showAsAction="never" android:title="保存塗鴉"/> <item android:id="@+id/clear" android:orderInCategory="100" android:showAsAction="never" android:title="清除數據"/> </menu>
Activity
/** * 畫板塗鴉 * 1.在內存中生成一張圖片 * 2.為ImageView設置這張圖片 * 3.設置畫布,畫筆 * 4.為ImageView設置監聽事件 * @author 劉楠 * * 2016-3-3下午7:28:20 */ public class MainActivity extends Activity implements OnClickListener, OnSeekBarChangeListener, OnTouchListener{ private static final String TAG = "MainActivity"; /* * 進度條,用來改變畫筆粗細 */ private SeekBar seekBar; /* * 畫筆的顏色 */ private View red; private View green; private View blue; private View yellow; private View purple; /* * 畫板 */ Canvas canvas ; /* * 畫筆 */ Paint paint; private ImageView ivResult; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * 畫板要畫的地方 */ ivResult = (ImageView) findViewById(R.id.iv_result); /* * 進度條,用來改變畫筆粗細 */ seekBar = (SeekBar) findViewById(R.id.seekbar); /* * 畫筆的顏色 */ red = findViewById(R.id.red); green = findViewById(R.id.green); blue = findViewById(R.id.blue); yellow = findViewById(R.id.yellow); purple = findViewById(R.id.purple); /* * 設置監聽事件 */ red.setOnClickListener(this); green.setOnClickListener(this); blue.setOnClickListener(this); yellow.setOnClickListener(this); purple.setOnClickListener(this); seekBar.setOnSeekBarChangeListener(this); /* * 內存中的圖 */ buffImage = Bitmap.createBitmap(300, 300, Config.ARGB_8888); /* * 畫板 */ canvas = new Canvas(buffImage); canvas.drawColor(Color.WHITE); /* * 畫布 */ paint = new Paint(); paint.setStrokeCap(Cap.ROUND); ivResult.setImageBitmap(buffImage); ivResult.setOnTouchListener(this); } /** * 進度條改變時 */ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } /** * 進度條觸摸時 */ @Override public void onStartTrackingTouch(SeekBar seekBar) { } /** * 進度條停止 */ @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); paint.setStrokeWidth(progress); Toast.makeText(this, "當前畫筆粗細是:"+progress, Toast.LENGTH_SHORT).show(); } /** * 單擊事件監聽器 */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.red: paint.setColor(Color.RED); Log.d(TAG,"畫筆顏色:紅色"); break; case R.id.green: paint.setColor(Color.GREEN); Log.d(TAG,"畫筆顏色:綠色"); break; case R.id.blue: paint.setColor(Color.BLUE); Log.d(TAG,"畫筆顏色:藍色"); break; case R.id.yellow: paint.setColor(Color.YELLOW); Log.d(TAG,"畫筆顏色:黃色"); break; case R.id.purple: paint.setColor(0xffff00ff); Log.d(TAG,"畫筆顏色:祡色"); break; } } float startX ; float startY; /* * 內存中的圖 */ private Bitmap buffImage; /** * ImageView觸摸事件 */ @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d(TAG, "down---"+event.getX()+" ::: "+event.getY()); startX = event.getX(); startY = event.getY(); canvas.drawLine(startX, startY, startX, startY, paint); ivResult.setImageBitmap(buffImage); break; case MotionEvent.ACTION_MOVE: Log.d(TAG, "move---"+event.getX()+" ::: "+event.getY()); float stopX = event.getX(); float stopY = event.getY(); canvas.drawLine(startX, startY, stopX, stopY, paint); ivResult.setImageBitmap(buffImage); startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_UP: Log.d(TAG, "up---"+event.getX()+" ::: "+event.getY()); break; } return true; } /** * 添加菜單 */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } /** * 菜單被選擇時的事件保存圖片與清除圖片 */ @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case R.id.save: File file = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis()+".jpg"); try { OutputStream out = new FileOutputStream(file); buffImage.compress(CompressFormat.JPEG, 100, out); Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show(); } catch (FileNotFoundException e) { e.printStackTrace(); } /* * 發送通知告訴系統新增加了一張圖片 */ Intent intent =new Intent(); intent.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); //發送數據 intent.setData(Uri.fromFile(file)); //發送廣播 sendBroadcast(intent); break; case R.id.clear: /* * 清除畫板 */ canvas.drawColor(Color.WHITE); ivResult.setImageBitmap(buffImage); break; } return super.onMenuItemSelected(featureId, item); } }
保存在SD卡上的權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
getX和getRawX的區別
當前的觸摸位置到控件的左邊間距
當前的觸摸位置到屏幕的左邊間距
原理:
布局 <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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/after" /> <ImageView android:id="@+id/pre" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
Activty實現
/** * 撕衣服 * 1.准備兩張一樣的圖片,一張是穿有衣服的,另一張是沒有穿衣服的。 2.通過FrameLayout進行布局或者相對布局這裡使用相對,穿衣服的放上面,沒穿衣服的圖片放下面。 3.通過觸摸事件進行判斷,手指劃過的地方,讓穿衣服的圖片變成透明,就顯示到了下面沒穿衣服的圖片。 * @author 劉楠 * * 2016-3-3下午11:22:08 */ public class MainActivity extends Activity implements OnTouchListener { private static final String TAG = "MainActivity"; /* * 前面的一張圖片 */ private ImageView pre; private Canvas canvas; private Bitmap buffImage; private static final int RADIUS = 10; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pre = (ImageView) findViewById(R.id.pre); /* * 通過這種方法讀取的bitmap是只讀的,不可修改 */ Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre); /* * 內存中的生成一張同樣大小與配置的圖片 */ buffImage = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig()); canvas = new Canvas(buffImage); Paint paint = new Paint(); Matrix matrix = new Matrix(); /* * 畫圖 */ canvas.drawBitmap(bitmap, matrix, paint); pre.setImageBitmap(buffImage); /* * 設置監聽事件 */ pre.setOnTouchListener(this); } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: Log.d(TAG, "move" + event.getX() + "------->" + event.getY()); int stopX = (int) event.getX(); int stopY = (int) event.getY(); // 這個判斷是計算邊界,因為超過了邊界為負值時會報錯 if (stopX >= RADIUS && stopX <= pre.getWidth() - RADIUS && stopY >= RADIUS && stopY <= pre.getHeight() - RADIUS) { /** * 計算圓,挖空一個半徑為RADIUS的實心圓 */ for (int radius = 0; radius <= RADIUS; radius++) { for (double angle = 0; angle <= 360; angle++) { int newX = (int) (stopX + radius * Math.cos(angle)); int newY = (int) (stopY + radius * Math.sin(angle)); buffImage.setPixel(newX, newY, Color.TRANSPARENT); } } pre.setImageBitmap(buffImage); } break; } return true; } }
布局
<LinearLayout 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:gravity="center_horizontal" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" android:text="調色板" /> <SeekBar android:id="@+id/seekbar_red" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="50" android:max="100"/> <SeekBar android:id="@+id/seekbar_green" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="50" android:max="100"/> <SeekBar android:id="@+id/seekbar_blue" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="50" android:max="100"/> <SeekBar android:id="@+id/seekbar_alpha" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="50" android:max="100"/> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
Activity
/** * 簡易調色板 步驟: 1.使用SeekBar來控制顏色的顯示比例 * * * @author 劉楠 * * 2016-3-3下午10:58:24 */ public class MainActivity extends Activity { private SeekBar seekbarRed; private ImageView iv; private Paint paint; private Matrix matrix; private Canvas canvas; private SeekBar seekbarGreen; private SeekBar seekbarBlue; private SeekBar seekbarAlpha; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); seekbarRed = (SeekBar) findViewById(R.id.seekbar_red); seekbarGreen = (SeekBar) findViewById(R.id.seekbar_green); seekbarBlue = (SeekBar) findViewById(R.id.seekbar_blue); seekbarAlpha = (SeekBar) findViewById(R.id.seekbar_alpha); iv = (ImageView) findViewById(R.id.iv); // 通過這種方法讀取的bitmap是只讀的,不可修改 final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre14); final Bitmap buffImage = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig()); canvas = new Canvas(buffImage); paint = new Paint(); matrix = new Matrix(); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); seekbarRed.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); float value = progress / 50.0f; ColorMatrix cm = new ColorMatrix(); /* * * 顏色矩陣 */ cm.set(new float[] { 1 * value, 0, 0, 0, 0,// 紅色 0, 1, 0, 0, 0,// 綠色 0, 0, 1, 0, 0,// 藍色 0, 0, 0, 1, 0,// 透明度 }); // 給畫筆添加過濾器 // 給畫筆添加顏色過濾器 paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { float value = progress / 50.0f; ColorMatrix cm = new ColorMatrix(); /* * * 顏色矩陣 */ cm.set(new float[] { 1 * value, 0, 0, 0, 0,// 紅色 0, 1, 0, 0, 0,// 綠色 0, 0, 1, 0, 0,// 藍色 0, 0, 0, 1, 0,// 透明度 }); // 給畫筆添加過濾器 // 給畫筆添加顏色過濾器 paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); } }); seekbarGreen.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); float value = progress / 50.0f; ColorMatrix cm = new ColorMatrix(); /* * * 顏色矩陣 */ cm.set(new float[] { 1, 0, 0, 0, 0,// 紅色 0, 1 * value, 0, 0, 0,// 綠色 0, 0, 1, 0, 0,// 藍色 0, 0, 0, 1, 0,// 透明度 }); // 給畫筆添加過濾器 // 給畫筆添加顏色過濾器 paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { float value = progress / 50.0f; ColorMatrix cm = new ColorMatrix(); /* * * 顏色矩陣 */ cm.set(new float[] { 1, 0, 0, 0, 0,// 紅色 0, 1 * value, 0, 0, 0,// 綠色 0, 0, 1, 0, 0,// 藍色 0, 0, 0, 1, 0,// 透明度 }); // 給畫筆添加過濾器 // 給畫筆添加顏色過濾器 paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); } }); seekbarBlue.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); float value = progress / 50.0f; ColorMatrix cm = new ColorMatrix(); /* * * 顏色矩陣 */ cm.set(new float[] { 1, 0, 0, 0, 0,// 紅色 0, 1, 0, 0, 0,// 綠色 0, 0, 1 * value, 0, 0,// 藍色 0, 0, 0, 1, 0,// 透明度 }); // 給畫筆添加過濾器 // 給畫筆添加顏色過濾器 paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { float value = progress / 50.0f; ColorMatrix cm = new ColorMatrix(); cm.set(new float[] { 1, 0, 0, 0, 0,// 紅色 0, 1, 0, 0, 0,// 綠色 0, 0, 1 * value, 0, 0,// 藍色 0, 0, 0, 1, 0,// 透明度 }); // 給畫筆添加過濾器 // 給畫筆添加顏色過濾器 paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); } }); seekbarAlpha.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); float value = progress / 50.0f; ColorMatrix cm = new ColorMatrix(); cm.set(new float[] { 1, 0, 0, 0, 0,// 紅色 0, 1, 0, 0, 0,// 綠色 0, 0, 1, 0, 0,// 藍色 0, 0, 0, 1 * value, 0,// 透明度 }); // 給畫筆添加過濾器 // 給畫筆添加顏色過濾器 paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { float value = progress / 50.0f; ColorMatrix cm = new ColorMatrix(); cm.set(new float[] { 1, 0, 0, 0, 0,// 紅色 0, 1, 0, 0, 0,// 綠色 0, 0, 1, 0, 0,// 藍色 0, 0, 0, 1 * value, 0,// 透明度 }); // 給畫筆添加過濾器 // 給畫筆添加顏色過濾器 paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(bitmap, matrix, paint); iv.setImageBitmap(buffImage); } }); } }
Android自定義View入門(一),androidview最近在寫一個關於音樂播放的應用,寫到播放界面UI時,就想自己實現的一個播放界面。那麼如何實現自定義View呢
Android開發案例,android案例所有電商APP的商品詳情頁面幾乎都是和淘寶的一模一樣(見下圖): 采用上下分頁的模式 商品基本參數 & 選購參數在上頁
Android編程之客戶端通過socket與服務器通信的方法 Android編程之客戶端通過socket與服務器通信的方法 &n
Android系統默認對話框添加圖片,開發工具Android Studio 今天公司UI要求軟件對話框改成加圖片的,以前沒有做過,所以就學習了一下,廢話不多說, 看效果: