zoukankan      html  css  js  c++  java
  • Android 相册图片选取+自定义裁剪方式(非系统裁剪)

    不多说,直接上代码(裁剪的代码摘自网络。)(项目可运行)

    主要是系统自身的剪切方式在有些机型上会程序崩溃的问题。

     1 package com.jichun.activity;
     2 
     3 import java.io.FileNotFoundException;
     4 
     5 import com.jichun.view.CropCanvas;
     6 
     7 import android.app.Activity;
     8 import android.content.ContentResolver;
     9 import android.content.Intent;
    10 import android.graphics.Bitmap;
    11 import android.graphics.BitmapFactory;
    12 import android.net.Uri;
    13 import android.os.Bundle;
    14 import android.view.View;
    15 import android.view.View.OnClickListener;
    16 import android.widget.ImageButton;
    17 import android.widget.ImageView;
    18 
    19 public class MainActivity extends Activity {
    20     private CropCanvas canvas = null;
    21     
    22     /** Called when the activity is first created. */
    23     @Override
    24     public void onCreate(Bundle savedInstanceState) {
    25         super.onCreate(savedInstanceState);
    26         setContentView(R.layout.main);
    27         //创建确定按钮
    28         ImageButton confirmBtn = (ImageButton) findViewById(R.id.confirm_button);
    29         confirmBtn.setOnClickListener(new OnClickListener() {
    30             
    31             @Override
    32             public void onClick(View view) {
    33                 confirmFunction();
    34             }
    35         });
    36         ImageButton exitBtn = (ImageButton) findViewById(R.id.exit_button);
    37         exitBtn.setOnClickListener(new OnClickListener() {
    38             
    39             @Override
    40             public void onClick(View view) {
    41                 exitFunction(view);
    42             }
    43         });
    44         this.gallery();
    45     }
    46     
    47     /*
    48      * 从相册获取
    49      */
    50     public void gallery() {
    51         // 激活系统图库,选择一张图片
    52         Intent intent = new Intent(Intent.ACTION_PICK);
    53         intent.setType("image/*");
    54         // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_GALLERY
    55         startActivityForResult(intent, 112);
    56     }
    57     
    58     @Override
    59     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    60         super.onActivityResult(requestCode, resultCode, data);
    61         if (requestCode == 112) {
    62             // 从相册返回的数据
    63             if (data != null) {
    64                 // 得到图片的全路径
    65                 Uri uri = data.getData();
    66                 ContentResolver content_resolver = this.getContentResolver();
    67                 try {
    68                     Bitmap bmp = BitmapFactory.decodeStream(content_resolver.openInputStream(uri));
    69                     canvas = (CropCanvas)findViewById(R.id.myCanvas);
    70                     canvas.setBitmap(bmp);
    71                 } catch (FileNotFoundException e) {
    72                     // TODO Auto-generated catch block
    73                     e.printStackTrace();
    74                 }
    75             }
    76         }
    77         
    78     }
    79     
    80     public void confirmFunction(){
    81         canvas.setBitmap(canvas.getSubsetBitmap());
    82     }
    83     
    84     public void exitFunction(View view){
    85         this.finish();
    86     }
    87 }
      1 package com.jichun.view;
      2 
      3 import android.content.Context;
      4 import android.graphics.Bitmap;
      5 import android.graphics.Canvas;
      6 import android.graphics.Color;
      7 import android.graphics.Matrix;
      8 import android.graphics.Paint;
      9 import android.graphics.Rect;
     10 import android.graphics.RectF;
     11 import android.graphics.Bitmap.Config;
     12 import android.graphics.drawable.BitmapDrawable;
     13 import android.util.AttributeSet;
     14 import android.view.MotionEvent;
     15 import android.widget.ImageView;
     16 
     17 public class CropCanvas extends ImageView {
     18 
     19     private final static int PRESS_LB = 0;//表示左下角矩形框
     20     private final static int PRESS_LT = 1;//表示左上角矩形框
     21     private final static int PRESS_RB = 2;//表示右下角矩形框
     22     private final static int PRESS_RT = 3;//表示右上角矩形框
     23 
     24     private Bitmap bitMap = null;                //原始图片
     25     private RectF src = null;                    //经过比例转换后的裁剪区域
     26     private RectF dst = null;                    //图片显示区域(可被裁剪的区域大小)
     27     private RectF ChooseArea = null;            //选择需要裁剪的区域                
     28     private Paint mPaint = null;                //画笔
     29     private Matrix matrix = null;                //矩阵
     30     
     31     private int mx = 0;                            //存储触笔移动时,之前所在的触笔的x坐标
     32     private int my = 0;                            //存储触笔移动时,之前所在的触笔的y坐标
     33     private boolean touchFlag = false;            //触笔是否在屏幕之上
     34     private boolean cutFlag = false;            //是否点击了menu上的裁剪按钮
     35     private int recFlag = -1;                    //用来存储触笔点击了哪个小矩形框(改变选择区域大小的小矩形框)
     36     private boolean firstFlag = false;
     37     
     38     private RectF recLT = null;                    //左上角的小矩形框
     39     private RectF recRT = null;                    //右上角的小矩形框
     40     private RectF recLB = null;                    //左下角的小矩形框
     41     private RectF recRB = null;                    //右下角的小矩形框
     42     private static final int LEFT_AREA_ALPHA = 50 * 255 / 100;
     43     private RectF leftRectL = null;
     44     private RectF leftRectR = null;
     45     private RectF leftRectT = null;
     46     private RectF leftRectB = null;
     47     private Paint leftAreaPaint = null;
     48     
     49     public CropCanvas(Context context, AttributeSet attrs) {
     50         super(context, attrs);
     51         this.init();
     52     }
     53     
     54     public CropCanvas(Context context) {
     55         super(context);
     56         this.init();
     57     } 
     58     
     59     public void init(){
     60         cutFlag = true;
     61         recLT = new RectF();
     62         recLB = new RectF();
     63         recRT = new RectF();
     64         recRB = new RectF();
     65         dst = new RectF();
     66         mPaint = new Paint();
     67         mPaint.setColor(Color.RED);
     68         mPaint.setStyle(Paint.Style.STROKE);      //将画笔的风格改为空心
     69         mPaint.setStrokeWidth(2);
     70         ChooseArea = new RectF();
     71         this.setPressRecLoc();
     72         src = null;
     73         firstFlag = true;
     74         
     75         //选择框之外的灰色区域,分成四个矩形框
     76         
     77         leftAreaPaint = new Paint();
     78         leftAreaPaint.setStyle(Paint.Style.FILL);
     79         leftAreaPaint.setAlpha(CropCanvas.LEFT_AREA_ALPHA);
     80     }
     81     
     82     public void setBitmap(Bitmap bitmap){
     83         BitmapDrawable bd = new BitmapDrawable(bitmap);
     84         src = new RectF(0,0,bd.getIntrinsicWidth(),bd.getIntrinsicHeight());
     85         this.bitMap = bitmap.copy(Config.ARGB_8888, true);
     86         
     87         this.setImageBitmap(bitMap);
     88         leftRectB = new RectF();
     89         leftRectL = new RectF();
     90         leftRectR = new RectF();
     91         leftRectT = new RectF();
     92     }
     93     
     94     public void imageScale(){
     95         matrix = this.getImageMatrix();
     96         matrix.mapRect(dst, src);
     97         int padding = this.getPaddingBottom();
     98         dst.set(dst.left+padding,dst.top+padding,dst.right+padding,dst.bottom+padding);
     99         ChooseArea = new RectF(dst.left+40,dst.top+40,dst.right-40,dst.bottom-40);
    100         this.setPressRecLoc();
    101         this.invalidate();
    102     }
    103     
    104     //裁剪出选择区域里的图片
    105     //之前要做比例转换,因为,你选择的区域是针对比例转换后的图片
    106     //所以要使用ChooseArea的数值做比例转换,然后,使用这些数值重新设置rec的大小
    107     public Bitmap getSubsetBitmap(){
    108         float ratioWidth = bitMap.getWidth()/(float)(dst.right-dst.left);
    109         float ratioHeight = bitMap.getHeight()/(float)(dst.bottom - dst.top);
    110         int left = (int)((ChooseArea.left - dst.left) * ratioWidth);
    111         int right = (int)(left + (ChooseArea.right - ChooseArea.left) * ratioWidth);
    112         int top = (int)((ChooseArea.top - dst.top) * ratioHeight);
    113         int bottom = (int)(top + (ChooseArea.bottom - ChooseArea.top) * ratioHeight);
    114         src = new RectF(left,top,right,bottom);
    115         firstFlag = true;
    116         set_LeftArea_Alpha();
    117         return Bitmap.createBitmap(bitMap, left, top, right-left, bottom-top);
    118     }
    119     
    120     //获得ChooseArea对象
    121     public RectF getChooseArea(){
    122         return ChooseArea;
    123     }
    124     
    125     //移动选择区域,选择区域是不能从图片区域里移出去的
    126     public void moveChooseArea(int move_x,int move_y){
    127         if(ChooseArea.left + move_x >= dst.left && ChooseArea.right + move_x <= dst.right
    128         && ChooseArea.top + move_y >= dst.top && ChooseArea.bottom + move_y <= dst.bottom){
    129             ChooseArea.set(ChooseArea.left + move_x,ChooseArea.top+move_y
    130                     ,ChooseArea.right + move_x,ChooseArea.bottom+move_y);
    131         }else{
    132             if(ChooseArea.left + move_x < dst.left){
    133                 ChooseArea.set(dst.left,ChooseArea.top
    134                         ,ChooseArea.right+dst.left-ChooseArea.left,ChooseArea.bottom);
    135             }
    136             if(ChooseArea.right + move_x > dst.right){
    137                 ChooseArea.set(ChooseArea.left+dst.right-ChooseArea.right,ChooseArea.top
    138                         ,dst.right,ChooseArea.bottom);
    139             }
    140             
    141             if(ChooseArea.top + move_y < dst.top){
    142                 ChooseArea.set(ChooseArea.left,dst.top
    143                         ,ChooseArea.right,ChooseArea.bottom+dst.top-ChooseArea.top);
    144             }
    145             
    146             if(ChooseArea.bottom + move_y > dst.bottom){
    147                 ChooseArea.set(ChooseArea.left,ChooseArea.top+dst.bottom-ChooseArea.bottom
    148                         ,ChooseArea.right,dst.bottom);
    149             }
    150         }
    151         this.setPressRecLoc();
    152         mPaint.setColor(Color.GREEN);
    153         this.invalidate();
    154     }
    155     
    156     public boolean onTouchEvent(MotionEvent event){
    157         mPaint.setColor(Color.RED);
    158         
    159         //点击了裁剪按钮之后才会执行以下事件
    160         if(event.getAction() == MotionEvent.ACTION_DOWN && cutFlag){
    161             //System.out.println(event.getX() + "," + event.getY());
    162             //判断触笔是否在裁剪区域内,也就是ChooseArea内
    163             //如果是,整个区域随着鼠标移动而移动
    164             mx = (int)event.getX();
    165             my = (int)event.getY();
    166             if(this.judgeLocation(mx,my)){
    167                 touchFlag = true;
    168                 mPaint.setColor(Color.GREEN);
    169                 this.invalidate();
    170                 return true;
    171             }else{
    172                 //不在裁剪区域内,就判断触笔是否在改变区域大小的小矩形框之内
    173                 if(this.findPresseddst((int)event.getX(), (int)event.getY())){
    174                     touchFlag = true;
    175                     mPaint.setColor(Color.RED);
    176                     return true;
    177                 }
    178             }
    179         }
    180         
    181         if(event.getAction() == MotionEvent.ACTION_MOVE && touchFlag){
    182             //判断是否点击了哪个个小矩形框
    183             if(this.isOutOfArea((int)event.getX(), (int)event.getY())){
    184                 return true;
    185             }
    186             
    187             //如果选择区域大小跟图像大小一样时,就不能移动
    188             if(ChooseArea.left == dst.left && ChooseArea.top == dst.top &&
    189                ChooseArea.right == dst.right && ChooseArea.bottom == dst.bottom){
    190             }else{
    191                 this.moveChooseArea((int)event.getX() - mx, (int)event.getY() - my);
    192                 mx = (int)event.getX();
    193                 my = (int)event.getY();
    194             }
    195         }
    196         
    197         //触笔移出屏幕时,将一些变量设回初值
    198         if(event.getAction() == MotionEvent.ACTION_UP){
    199             recFlag = -1;
    200             this.invalidate();
    201             touchFlag = false;
    202         }
    203         
    204         return super.onTouchEvent(event);
    205     }
    206     
    207     
    208     
    209     //判断是否要超出图片区域,这个函数会调用下面四个press打头的函数
    210     //这个函数也会重绘整个画布,也就是选择区域会随着鼠标的移动改变
    211     private boolean isOutOfArea(int x,int y){
    212         switch(recFlag){
    213         case CropCanvas.PRESS_LB:
    214             this.pressLB(x - mx, y - my);
    215             break;
    216         case CropCanvas.PRESS_LT:
    217             this.pressLT(x - mx, y - my);
    218             break;
    219         case CropCanvas.PRESS_RB:
    220             this.pressRB(x - mx, y - my);
    221             break;
    222         case CropCanvas.PRESS_RT:
    223             this.pressRT(x - mx, y - my);
    224             break;
    225         default:return false;
    226         }
    227         mx = x;
    228         my = y;
    229         this.invalidate();
    230         return true;
    231     }
    232     
    233     //找到点击了哪个矩形框(改变选择区域大小的小矩形框)
    234     //这个是在MotionEvent.ACTION_DOWN这个动作时执行的
    235     //是为了在MotionEvent.ACTION_MOVE的时候,知道应该移动哪个小矩形框
    236     public boolean findPresseddst(int x,int y){
    237         boolean returnFlag = false;
    238         if(this.isInRect(x, y, recLB)){
    239             recFlag = CropCanvas.PRESS_LB;
    240             returnFlag = true;
    241         }else if(this.isInRect(x, y, recLT)){
    242             recFlag = CropCanvas.PRESS_LT;
    243             returnFlag = true;
    244         }else if(this.isInRect(x, y, recRB)){
    245             recFlag = CropCanvas.PRESS_RB;
    246             returnFlag = true;
    247         }else if(this.isInRect(x, y, recRT)){
    248             recFlag = CropCanvas.PRESS_RT;
    249             returnFlag = true;
    250         }
    251         
    252         return returnFlag;
    253     }
    254     
    255     public boolean isInRect(int x,int y,RectF rect){
    256         if(x >= rect.left -20 && x <= rect.right + 20 && y > rect.top - 20 && y < rect.bottom + 20){
    257             return true;
    258         }
    259         return false;
    260     }
    261     
    262     //点击角落矩形框改变选择区域大小时,不能超过图片所在的区域
    263     //下面以press打头的四个函数就是判断是否超出图片区域
    264     //如果超出了,就移动不了
    265     //不超出按照触笔移动的距离来移动小矩形框
    266     
    267     //pressLB是当点击左下角小矩形框改变大小时是否超出图片区域
    268     //如果超出就将left与bottom的值设为图片区域的left和bottom
    269     private void pressLB(int x,int y){
    270         float left = ChooseArea.left + x;
    271         float right = ChooseArea.right;
    272         float top = ChooseArea.top;
    273         float bottom = ChooseArea.bottom + y;
    274         if(left <= right - 30 && left >= dst.left && bottom <= dst.bottom && bottom >= top + 30){
    275                 ChooseArea.set(left,top,right,bottom);
    276         }else{
    277             if(left + x < dst.left){
    278                 left = dst.left;
    279             }
    280             
    281             if(bottom + y > dst.bottom){
    282                 bottom = dst.bottom;
    283             }
    284             
    285             if(ChooseArea.left + x > ChooseArea.right - 30){
    286                 left = ChooseArea.right - 30;
    287             }
    288             
    289             if(ChooseArea.bottom + y < ChooseArea.top + 30){
    290                 bottom = ChooseArea.top + 30;
    291             }
    292             ChooseArea.set(left,top,right,bottom);
    293         }
    294         this.setPressRecLoc();
    295     }
    296     
    297     //pressLT是当点击左上角小矩形框改变大小时是否超出图片区域
    298     //如果超出就将left与top的值设为图片区域的left和top
    299     private void pressLT(int x,int y){
    300         float left = ChooseArea.left + x;
    301         float right = ChooseArea.right;
    302         float top = ChooseArea.top + y;
    303         float bottom = ChooseArea.bottom;
    304         if(left <= right - 30 && left >= dst.left && top <= bottom - 30 && top >= dst.top){
    305             ChooseArea.set(left,top,right,bottom);
    306         }else{
    307             if(left < dst.left){
    308                 left = dst.left;
    309             }
    310             
    311             if(top < dst.top){
    312                 top = dst.top;
    313             }
    314             
    315             if(left > right - 30){
    316                 left = right - 30;
    317             }
    318             
    319             if(top > bottom - 30){
    320                 top = bottom - 30;
    321             }
    322             ChooseArea.set(left,top,right,bottom);
    323         }
    324         this.setPressRecLoc();
    325     }
    326     
    327     //pressRT是当点击右上角小矩形框改变大小时是否超出图片区域
    328     //如果超出就将right与top的值设为图片区域的right和top
    329     private void pressRT(int x,int y){
    330         float left = ChooseArea.left;
    331         float right = ChooseArea.right + x;
    332         float top = ChooseArea.top + y;
    333         float bottom = ChooseArea.bottom;
    334         
    335         if(right <= dst.right && right >= left + 30 && top <= bottom - 30 && top >= dst.top){
    336             ChooseArea.set(left,top,right,bottom);
    337         }else{
    338             if(right > dst.right){
    339                 right = dst.right;
    340             }
    341             
    342             if(top < dst.top){
    343                 top = dst.top;
    344             }
    345             
    346             if(right < left + 30){
    347                 right = left + 30;
    348             }
    349             
    350             if(top > bottom - 30){
    351                 top = bottom - 30;
    352             }
    353             ChooseArea.set(left,top,right,bottom);
    354         }
    355         this.setPressRecLoc();
    356     }
    357     
    358     //pressRB是当点击右下角小矩形框改变大小时是否超出图片区域
    359     //如果超出就将right与bottom的值设为图片区域的right和bottom
    360     private void pressRB(int x,int y){
    361         float left = ChooseArea.left;
    362         float right = ChooseArea.right + x;
    363         float top = ChooseArea.top;
    364         float bottom = ChooseArea.bottom + y;
    365         
    366         if(right<= dst.right && right >= left + 30 && bottom <= dst.bottom && bottom >= top + 30){
    367             ChooseArea.set(left,top,right,bottom);
    368         }else{
    369             if(right > dst.right){
    370                 right = dst.right;
    371             }
    372             
    373             if(bottom > dst.bottom){
    374                 bottom = dst.bottom;
    375             }
    376             
    377             if(right < left + 30){
    378                 right = left + 30;
    379             }
    380             
    381             if(bottom < top + 30){
    382                 bottom = top + 30;
    383             }
    384             ChooseArea.set(left,top,right,bottom);
    385         }
    386         this.setPressRecLoc();
    387     }
    388     
    389     //每次改变选择区域矩形的大小或者移动,各角落上的小矩形也要改变它的Location
    390     private void setPressRecLoc(){
    391         recLT.set(ChooseArea.left-8,ChooseArea.top-8 , ChooseArea.left+8, ChooseArea.top+8);
    392         recLB.set(ChooseArea.left-8,ChooseArea.bottom-8 , ChooseArea.left+8, ChooseArea.bottom+8);
    393         recRT.set(ChooseArea.right-8,ChooseArea.top-8 , ChooseArea.right+8, ChooseArea.top+8);
    394         recRB.set(ChooseArea.right-8,ChooseArea.bottom-8 , ChooseArea.right+8, ChooseArea.bottom+8);
    395     }
    396     
    397     //判断触笔是否在选择区域内
    398     public boolean judgeLocation(float x,float y){
    399         float start_x = this.getChooseArea().left;
    400         float start_y = this.getChooseArea().top;
    401         float last_x = this.getChooseArea().right;
    402         float last_y = this.getChooseArea().bottom;
    403         //System.out.println("chubi:" + x + "," + y);
    404         //System.out.println(start_y + "," + last_y);
    405         if(x > start_x+10 && x < last_x-10 && y > start_y+10 && y < last_y-10){
    406             return true;
    407         }
    408         return false;
    409     }
    410     
    411     public void onDraw(Canvas canvas){
    412         super.onDraw(canvas);
    413         if(firstFlag){
    414             this.imageScale();
    415             firstFlag = false;
    416             mPaint.setColor(Color.RED);
    417             System.out.println("Width: " + (dst.right - dst.left));
    418             System.out.println("Height: " + (dst.bottom - dst.top));
    419             System.out.println("Width: " + this.getDrawable().getIntrinsicWidth());
    420             System.out.println("Height: " + this.getDrawable().getIntrinsicHeight());
    421         }else{
    422             set_LeftArea_Alpha();
    423         }
    424         canvas.drawRect(ChooseArea, mPaint);
    425         mPaint.setColor(Color.BLUE);
    426         canvas.drawRect(recLT, mPaint);
    427         canvas.drawRect(recLB, mPaint);
    428         canvas.drawRect(recRT, mPaint);   
    429         canvas.drawRect(recRB, mPaint);
    430         
    431         canvas.drawRect(leftRectL, leftAreaPaint);
    432         canvas.drawRect(leftRectR, leftAreaPaint);
    433         canvas.drawRect(leftRectT, leftAreaPaint);
    434         canvas.drawRect(leftRectB, leftAreaPaint);
    435         
    436     }
    437     
    438     public void set_LeftArea_Alpha(){
    439         leftRectL.set(dst.left, dst.top, ChooseArea.left, dst.bottom);
    440         leftRectR.set(ChooseArea.right,dst.top,dst.right,dst.bottom);
    441         leftRectT.set(ChooseArea.left, dst.top, ChooseArea.right, ChooseArea.top);
    442         leftRectB.set(ChooseArea.left,ChooseArea.bottom,ChooseArea.right,dst.bottom);
    443     } 
    444 }
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/layout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="150px"
            android:layout_alignParentTop="true"
            android:layout_weight="1"
            android:background="#191919"
            android:orientation="horizontal" >
        </LinearLayout>
    
        <com.jichun.view.CropCanvas
            android:id="@+id/myCanvas"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_marginBottom="5px"
            android:layout_marginTop="5px"
            android:layout_weight="1"
            android:background="#313131"
            android:padding="2dip" >
        </com.jichun.view.CropCanvas>
    
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="150px"
            android:layout_weight="1"
            android:background="#191919" >
    
            <ImageButton
                android:id="@+id/confirm_button"
                android:layout_width="70px"
                android:layout_height="fill_parent"
                android:layout_alignParentRight="true"
                android:background="#00000000"
                android:src="@drawable/confirmxml" >
            </ImageButton>
    
            <ImageButton
                 android:id="@+id/exit_button"
                android:layout_width="70px"
                android:layout_height="fill_parent"
                android:layout_alignParentLeft="true"
                android:background="#00000000"
                android:src="@drawable/exitxml" >
            </ImageButton>
        </RelativeLayout>
    
    </LinearLayout>
     1 <?xml version="1.0" encoding="utf-8" ?> 
     2 <selector xmlns:android="http://schemas.android.com/apk/res/android"> 
     3     <item android:state_window_focused="false" 
     4         android:drawable="@drawable/confirm" /> 
     5 
     6     <item android:state_focused="true" android:state_pressed="true" 
     7         android:drawable="@drawable/confirm_focus"  /> 
     8     <item android:state_focused="false" android:state_pressed="true" 
     9         android:drawable="@drawable/confirm_focus" /> 
    10 
    11     <item android:state_focused="true" 
    12         android:drawable="@drawable/confirm_focus" /> 
    13 </selector> 

    完整项目下载链接:http://pan.baidu.com/s/1c08a4Re

  • 相关阅读:
    《游戏引擎构架Game Engine Architecture》略读笔记
    Visual Studio快速入门(大纲)
    Linux课程学习 第四课
    Linux课程学习 第三课
    Linux课程学习 第二课
    vmware虚拟机安装centos7.3
    Win7 Linux双系统,恢复Linux启动项
    Java中Collection、Map常用实现类研究分析
    数据库计算每个表所占空间和记录数
    tomcat中部署多个项目,webAppRootKey 参数配置
  • 原文地址:https://www.cnblogs.com/vokie/p/3807774.html
Copyright © 2011-2022 走看看