• Android 举例说明自己的定义Camera图片和预览,以及前后摄像头切换


    如何调用本地图片,并调用系统拍摄的图像上一博文解释(http://blog.csdn.net/a123demi/article/details/40003695)的功能。

    而本博文将通过实例实现自己定义Camera的功效。详细功能例如以下:

    1.实现自己定义Camera拍照;

    2.实现前后置摄像头的切换。

    3.实现Camera拍照后图片缩小显示以及正常预览;

    4.实现Camera拍照后图片保存;

    在详细实现代码之前,我们先来了解一下Android api对实现自己定义Camera的介绍。


    依据api的介绍,对于Camera应用能够简单总结下面几个步骤。

    1.检查Camera是否存在。并在AndroidManifest.xml中赋予相关的权限

    2.创建一个继承于SurfaceView并实现SurfaceHolder接口的Camera Preview类

    3.在2的基础上新建一个Camera Preview布局文件

    4.设置一个拍照的监听事件,比如单击button事件等;

    5.实现拍照,并保存拍照后的图片到设备;

    6.释放Camera,以方便其它应用能够使用。

    以下将通过详细代码实现我们给出的三个功能。

    一.相关的xml文件

    1.AndroidManifest.xml相关配置以及相关权限,实现步骤一其中的权限配置

    <?xml version="1.0" encoding="utf-8"?

    > <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.camerasurfacedemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.camerasurfacedemo.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="com.example.camerasurfacedemo.CameraActivity" ></activity> <activity android:name="com.example.camerasurfacedemo.PreviewActivity" ></activity> </application> </manifest>


    2.activity_main.xml主函数入口。进入自己定义Camera界面入口,实现拍照后图片缩小显示功能

    <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" >
    "
    
        <Button
            android:id="@+id/id_go_camera_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="进入拍照界面" />
    
        <ImageView
            android:id="@+id/id_show_camera_iv"
            android:layout_width="150dp"
            android:layout_height="200dp"
            android:gravity="center" />
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="拍照图片显示区域"
            android:textColor="#FF0000"
            android:textSize="20sp" />
    
    </LinearLayout>

    3.activity_camera.xml自己定义Camera preview布局,实现步骤2,该界面实现前后置摄像头切换以及自己定义拍照等

    <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"
       	>
    	<LinearLayout
    	    android:id="@+id/id_process_btns_ll"
    	    android:layout_width="match_parent"
    	    android:layout_height="wrap_content"
    	    android:orientation="horizontal"
    	    android:layout_alignParentTop="true"
    	     >
    	    <Button 
    	        android:id="@+id/id_switch_camera_btn"
    	        android:layout_width="wrap_content"
    	        android:layout_height="wrap_content"
    	        android:layout_weight="1"
    	        android:gravity="center"
    	        android:text="切换前后摄像头"
    	        />
    	     <Button 
    	        android:id="@+id/id_capture_btn"
    	        android:layout_width="wrap_content"
    	        android:layout_height="wrap_content"
    	        android:layout_weight="1"
    	        android:gravity="center"
    	        android:text="拍照"
    	        />
    	</LinearLayout>
        <SurfaceView
            android:id="@+id/id_area_sv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/id_process_btns_ll"
            android:text="拍照区域" />
    
    </RelativeLayout>
    
    4.activity_preview.xml实现拍照后图片放大预览

    <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:background="#000000"
        android:orientation="vertical" >
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="拍照图片预览" 
            android:textColor="#FF0000"
            android:textSize="20sp"
            />
    
        <ImageView
            android:id="@+id/id_preview_camera_iv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center" />
    
    </LinearLayout>

    二.java代码实现

    1.帮助类HelpUtil.java

    package com.example.camerasurfacedemo;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import android.annotation.SuppressLint;
    import android.content.ContentResolver;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Matrix;
    import android.net.Uri;
    
    public class HelpUtil {
    	/**
    	 * 依据图片路径获取本地图片的Bitmap
    	 * 
    	 * @param url
    	 * @return
    	 */
    	public static Bitmap getBitmapByUrl(String url) {
    		FileInputStream fis = null;
    		Bitmap bitmap = null;
    		try {
    			fis = new FileInputStream(url);
    			bitmap = BitmapFactory.decodeStream(fis);
    
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			bitmap = null;
    		} finally {
    			if (fis != null) {
    				try {
    					fis.close();
    				} catch (IOException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				fis = null;
    			}
    		}
    
    		return bitmap;
    	}
    
    	/**
    	 * bitmap旋转90度
    	 * 
    	 * @param bitmap
    	 * @return
    	 */
    	public static Bitmap createRotateBitmap(Bitmap bitmap) {
    		if (bitmap != null) {
    			Matrix m = new Matrix();
    			try {
    				m.setRotate(90, bitmap.getWidth() / 2, bitmap.getHeight() / 2);// 90就是我们须要选择的90度
    				Bitmap bmp2 = Bitmap.createBitmap(bitmap, 0, 0,
    						bitmap.getWidth(), bitmap.getHeight(), m, true);
    				bitmap.recycle();
    				bitmap = bmp2;
    			} catch (Exception ex) {
    				System.out.print("创建图片失败。" + ex);
    			}
    		}
    		return bitmap;
    	}
    	
    	public static Bitmap getBitmapByUri(Uri uri,ContentResolver cr){
    		Bitmap bitmap = null;
    		try {
    			bitmap = BitmapFactory.decodeStream(cr
    					 .openInputStream(uri));
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			bitmap = null;
    		}
    		return bitmap;
    	}
    
    	/**
    	 * 获取格式化日期字符串
    	 * @param date
    	 * @return
    	 */
    	@SuppressLint("SimpleDateFormat")
    	public static String getDateFormatString(Date date) {
    		if (date == null)
    			date = new Date();
    		String formatStr = new String();
    		SimpleDateFormat matter = new SimpleDateFormat("yyyyMMdd_HHmmss");
    		formatStr = matter.format(date);
    		return formatStr;
    	}
    }
    

    2.主函数类MainActivity.java

    package com.example.camerasurfacedemo;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;
    
    public class MainActivity extends Activity {
    
    	private Button goCameraBtn;
    	private ImageView showCameraIv;
    	private static final int CAMERA_CODE = 1;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		goCameraBtn = (Button)this.findViewById(R.id.id_go_camera_btn);
    		goCameraBtn.setOnClickListener(new OnClickListener(){
    
    			@Override
    			public void onClick(View v) {
    				processGoCamera();
    			}
    			
    		});
    		
    		showCameraIv = (ImageView)this.findViewById(R.id.id_show_camera_iv);
    		showCameraIv.setOnClickListener(new OnClickListener(){
    
    			@Override
    			public void onClick(View v) {
    				processShowCamera(v);
    			}
    			
    		});
    	}
    	
    	/**
    	 * 处理进入camera事件
    	 */
    	private void processGoCamera(){
    		Intent intent = new Intent();
    		intent.setClass(this, CameraActivity.class);
    		startActivityForResult(intent,CAMERA_CODE);
    	}
    	
    	/**
    	 * 处理图片跳转进入预览界面
    	 */
    	private void processShowCamera(View v){
    		Intent intent = new Intent();
    		intent.setClass(this, PreviewActivity.class);
    		/**
    		 * 将图片url传给PreviewActivity
    		 */
    		intent.putExtra("cameraUrl", v.getContentDescription().toString());
    		startActivity(intent);
    	}
    	
    	@Override
    	public void onActivityResult(int requestCode,int resultCode,Intent data){
    		super.onActivityResult(requestCode, resultCode, data);
    		
    		if(RESULT_OK == resultCode){
    			if(CAMERA_CODE == requestCode){
    				/**
    				 * 获取activity返回的url
    				 */
    				Uri uri = data.getData();
    				String url = uri.toString().substring(uri.toString().indexOf("///")+2);
    				if(url != null && !TextUtils.isEmpty(url)){
    					showCameraIv.setContentDescription(url);
    					showCameraIv.setImageBitmap(HelpUtil.getBitmapByUrl(url));
    				}
    			}
    		}
    		
    	}
    
    }
    
    

    注意:这里通过startActivityForResult(intent,CAMERA_CODE)跳转和 onActivityResult(int requestCode,int resultCode,Intent data)返回拍照后的图片路径信息

    3.自己定义Camera preview类CameraActivity.java

    package com.example.camerasurfacedemo;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Date;
    
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.graphics.ImageFormat;
    import android.hardware.Camera;
    import android.hardware.Camera.CameraInfo;
    import android.hardware.Camera.Parameters;
    import android.hardware.Camera.PictureCallback;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.Window;
    import android.widget.Button;
    
    public class CameraActivity extends Activity implements OnClickListener,
    		SurfaceHolder.Callback {
    
    	private static final String TAG = CameraActivity.class.getSimpleName();
    	private static final int MEDIA_TYPE_IMAGE = 1;
    	private Button switchCameraBtn, captureBtn;
    	private SurfaceView surfaceSv;
    
    	private SurfaceHolder mHolder;
    	private Camera mCamera;
    	// 0表示后置,1表示前置
    	private int cameraPosition = 1;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		// 不显示标题
    		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.activity_camera);
    
    		findById();
    		initData();
    	}
    
    	/**
    	 * 初始化view
    	 */
    	private void findById() {
    		switchCameraBtn = (Button) this.findViewById(R.id.id_switch_camera_btn);
    		captureBtn = (Button) this.findViewById(R.id.id_capture_btn);
    		surfaceSv = (SurfaceView) this.findViewById(R.id.id_area_sv);
    
    		switchCameraBtn.setOnClickListener(this);
    		captureBtn.setOnClickListener(this);
    	}
    
    	/**
    	 * 初始化相关data
    	 */
    	private void initData() {
    		// 获得句柄
    		mHolder = surfaceSv.getHolder();
    		// 加入回调
    		mHolder.addCallback(this);
    	}
    
    	@Override
    	public void onStart() {
    		super.onStart();
    		if (this.checkCameraHardware(this) && (mCamera == null)) {
    			// 打开camera
    			mCamera = getCamera();
    			if (mHolder != null) {
    				setStartPreview(mCamera,mHolder);
    			}
    		}
    	}
    
    	private Camera getCamera() {
    		Camera camera = null;
    		try {
    			camera = Camera.open();
    		} catch (Exception e) {
    			// Camera is not available (in use or does not exist)
    			camera = null;
    			Log.e(TAG, "Camera is not available (in use or does not exist)");
    		}
    		return camera;
    	}
    
    	@Override
    	public void onPause() {
    		super.onPause();
    		/**
    		 * 记得释放camera。方便其它应用调用
    		 */
    		releaseCamera();
    	}
    
    	@Override
    	public void onDestroy() {
    		super.onDestroy();
    	}
    
    	/**
    	 * 释放mCamera
    	 */
    	private void releaseCamera() {
    		if (mCamera != null) {
    			mCamera.setPreviewCallback(null);
    			mCamera.stopPreview();// 停掉原来摄像头的预览
    			mCamera.release();
    			mCamera = null;
    		}
    	}
    
    	@Override
    	public void onClick(View v) {
    		switch (v.getId()) {
    		case R.id.id_switch_camera_btn:
    			// 切换前后摄像头
    			int cameraCount = 0;
    			CameraInfo cameraInfo = new CameraInfo();
    			cameraCount = Camera.getNumberOfCameras();// 得到摄像头的个数
    
    			for (int i = 0; i < cameraCount; i++) {
    				Camera.getCameraInfo(i, cameraInfo);// 得到每个摄像头的信息
    				if (cameraPosition == 1) {
    					// 如今是后置,变更为前置
    					if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
    						/**
    						 * 记得释放camera。方便其它应用调用
    						 */
    						releaseCamera();
    						// 打开当前选中的摄像头
    						mCamera = Camera.open(i);
    						// 通过surfaceview显示取景画面
    						setStartPreview(mCamera,mHolder);
    						cameraPosition = 0;
    						break;
    					}
    				} else {
    					// 如今是前置。 变更为后置
    					if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
    						/**
    						 * 记得释放camera,方便其它应用调用
    						 */
    						releaseCamera();
    						mCamera = Camera.open(i);
    						setStartPreview(mCamera,mHolder);
    						cameraPosition = 1;
    						break;
    					}
    				}
    
    			}
    			break;
    		case R.id.id_capture_btn:
    			// 拍照,设置相关參数
    			Camera.Parameters params = mCamera.getParameters();
    			params.setPictureFormat(ImageFormat.JPEG);
    			params.setPreviewSize(800, 400);
    			// 自己主动对焦
    			params.setFocusMode(Parameters.FOCUS_MODE_AUTO);
    			mCamera.setParameters(params);
    			mCamera.takePicture(null, null, picture);
    			break;
    		}
    	}
    
    	@Override
    	public void surfaceCreated(SurfaceHolder holder) {
    
    		setStartPreview(mCamera,mHolder);
    	}
    
    	@Override
    	public void surfaceChanged(SurfaceHolder holder, int format, int width,
    			int height) {
    		// If your preview can change or rotate, take care of those events here.
    		// Make sure to stop the preview before resizing or reformatting it.
    
    		if (mHolder.getSurface() == null) {
    			// preview surface does not exist
    			return;
    		}
    
    		// stop preview before making changes
    		try {
    			mCamera.stopPreview();
    		} catch (Exception e) {
    			// ignore: tried to stop a non-existent preview
    		}
    
    		// set preview size and make any resize, rotate or
    		// reformatting changes here
    
    		// start preview with new settings
    		setStartPreview(mCamera,mHolder);
    	}
    
    	@Override
    	public void surfaceDestroyed(SurfaceHolder holder) {
    		// 当surfaceview关闭时,关闭预览并释放资源
    		/**
    		 * 记得释放camera,方便其它应用调用
    		 */
    		releaseCamera();
    		holder = null;
    		surfaceSv = null;
    	}
    
    	/**
    	 * 创建png图片回调数据对象
    	 */
    	PictureCallback picture = new PictureCallback() {
    		@Override
    		public void onPictureTaken(byte[] data, Camera camera) {
    			File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
    			if (pictureFile == null) {
    				Log.d(TAG,
    						"Error creating media file, check storage permissions: ");
    				return;
    			}
    			try {
    				FileOutputStream fos = new FileOutputStream(pictureFile);
    				fos.write(data);
    				fos.close();
    				returnResult(pictureFile);
    			} catch (FileNotFoundException e) {
    				Log.d(TAG, "File not found: " + e.getMessage());
    			} catch (IOException e) {
    				Log.d(TAG, "Error accessing file: " + e.getMessage());
    			}
    		}
    	};
    
    	/**
    	 * Create a File for saving an image or video
    	 */
    	private static File getOutputMediaFile(int type) {
    		// To be safe, you should check that the SDCard is mounted
    		// using Environment.getExternalStorageState() before doing this.
    
    		File mediaStorageDir = new File(
    				Environment
    						.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
    				"MyCameraApp");
    		// This location works best if you want the created images to be shared
    		// between applications and persist after your app has been uninstalled.
    
    		// Create the storage directory if it does not exist
    		if (!mediaStorageDir.exists()) {
    			if (!mediaStorageDir.mkdirs()) {
    				Log.d("MyCameraApp", "failed to create directory");
    				return null;
    			}
    		}
    
    		// Create a media file name
    		String timeStamp = HelpUtil.getDateFormatString(new Date());
    		File mediaFile;
    		if (type == MEDIA_TYPE_IMAGE) {
    			mediaFile = new File(mediaStorageDir.getPath() + File.separator
    					+ "IMG_" + timeStamp + ".png");
    		} else {
    			return null;
    		}
    		return mediaFile;
    	}
    
    	/** Check if this device has a camera */
    	private boolean checkCameraHardware(Context context) {
    		if (context.getPackageManager().hasSystemFeature(
    				PackageManager.FEATURE_CAMERA)) {
    			// this device has a camera
    			return true;
    		} else {
    			// no camera on this device
    			return false;
    		}
    	}
    
    	/**
    	 * activity返回式返回拍照图片路径
    	 * @param mediaFile
    	 */
    	private void returnResult(File mediaFile) {
    		Intent intent = new Intent();
    		intent.setData(Uri.fromFile(mediaFile));
    		this.setResult(RESULT_OK, intent);
    		this.finish();
    	}
    	
    	/**
    	 * 设置camera显示取景画面,并预览
    	 * @param camera
    	 */
    	private void setStartPreview(Camera camera,SurfaceHolder holder){
    		try {
    			camera.setPreviewDisplay(holder);
    			camera.startPreview();
    		} catch (IOException e) {
    			Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    		}
    	}
    }
    
    

    注意:

    1.检查Camera是否存在

    /** Check if this device has a camera */
    	private boolean checkCameraHardware(Context context) {
    		if (context.getPackageManager().hasSystemFeature(
    				PackageManager.FEATURE_CAMERA)) {
    			// this device has a camera
    			return true;
    		} else {
    			// no camera on this device
    			return false;
    		}
    	}
    
    

    2.创建png格式的回调接口

    /**
    	 * 创建png图片回调数据对象
    	 */
    	PictureCallback picture = new PictureCallback() {
    		@Override
    		public void onPictureTaken(byte[] data, Camera camera) {
    			File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
    			if (pictureFile == null) {
    				Log.d(TAG,
    						"Error creating media file, check storage permissions: ");
    				return;
    			}
    			try {
    				FileOutputStream fos = new FileOutputStream(pictureFile);
    				fos.write(data);
    				fos.close();
    				returnResult(pictureFile);
    			} catch (FileNotFoundException e) {
    				Log.d(TAG, "File not found: " + e.getMessage());
    			} catch (IOException e) {
    				Log.d(TAG, "Error accessing file: " + e.getMessage());
    			}
    		}
    	};

    3.生成图片文件并保存

    /**
    	 * Create a File for saving an image or video
    	 */
    	private static File getOutputMediaFile(int type) {
    		// To be safe, you should check that the SDCard is mounted
    		// using Environment.getExternalStorageState() before doing this.
    
    		File mediaStorageDir = new File(
    				Environment
    						.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
    				"MyCameraApp");
    		// This location works best if you want the created images to be shared
    		// between applications and persist after your app has been uninstalled.
    
    		// Create the storage directory if it does not exist
    		if (!mediaStorageDir.exists()) {
    			if (!mediaStorageDir.mkdirs()) {
    				Log.d("MyCameraApp", "failed to create directory");
    				return null;
    			}
    		}
    
    		// Create a media file name
    		String timeStamp = HelpUtil.getDateFormatString(new Date());
    		File mediaFile;
    		if (type == MEDIA_TYPE_IMAGE) {
    			mediaFile = new File(mediaStorageDir.getPath() + File.separator
    					+ "IMG_" + timeStamp + ".png");
    		} else {
    			return null;
    		}
    		return mediaFile;
    	}

    4.Camera一定要release

    	/**
    	 * 释放mCamera
    	 */
    	private void releaseCamera() {
    		if (mCamera != null) {
    			mCamera.setPreviewCallback(null);
    			mCamera.stopPreview();// 停掉原来摄像头的预览
    			mCamera.release();
    			mCamera = null;
    		}
    	}

    5.Activity结果返回

    	/**
    	 * activity返回式返回拍照图片路径
    	 * @param mediaFile
    	 */
    	private void returnResult(File mediaFile) {
    		Intent intent = new Intent();
    		intent.setData(Uri.fromFile(mediaFile));
    		this.setResult(RESULT_OK, intent);
    		this.finish();
    	}
    	

    4.图片正常预览PreviewActivity.java

    package com.example.camerasurfacedemo;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.view.Window;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    public class PreviewActivity extends Activity {
    
    	private ImageView previewCameraIv;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.activity_preview);
    
    		
    		previewCameraIv = (ImageView)this.findViewById(R.id.id_preview_camera_iv);
    		
    		Intent intent = this.getIntent();
    		String cameraUrl = intent.getStringExtra("cameraUrl").toString();
    		if(cameraUrl != null && !TextUtils.isEmpty(cameraUrl)){
    			previewCameraIv.setImageBitmap(HelpUtil.getBitmapByUrl(cameraUrl));
    		}else{
    			Toast.makeText(this, "图片路径错误", Toast.LENGTH_SHORT).show();
    		}
    	}
    	
    
    }
    
    

    以上就是本博文的全部内容。谢谢品读。

    源代码路径:http://download.csdn.net/detail/a123demi/8029265


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    VC 透明滑动控件Slider Control
    VC 对话框背景颜色、控件颜色
    VS2008下直接安装使用Boost库1.46.1版本
    强大的CImage类
    用CImage类来显示PNG、JPG等图片
    VS2008+Qt 项目目录
    java 中几种常用数据结构
    数据结构与算法——常用数据结构及其Java实现
    C++常用数据结构的实现
    基础数据结构和算法概念
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4908283.html
Copyright © 2020-2023  润新知