2015-04-14 170 views
1

我正在实现一个应用程序,其中有两个图像。第一个图像是静态的,或者说为android“拖动&下降”概念和第二个图像是“可拖动”的“下落目标”。可拖动的图像被拖动并放置在其他图像上。直到这一点的应用程序工作得很好,但我坚持如何保存这个叠加图像。如何在叠加其他图像后合并/保存图像?

在这里,我提供我做了什么至今:

DragNDropActivity.java

private static final String TAG = DragNDropActivity.class.getSimpleName(); 
private ImageView m_ivImage1, finalImage, sourceImage, targetImage, 
     testImage; 
private int m_counter = 0; 
float m_lastTouchX, m_lastTouchY, m_posX, m_posY, m_prevX, m_prevY, 
     m_imgXB, m_imgYB, m_imgXC, m_imgYC, m_dx, m_dy; 
private LinearLayout m_llTop; 
private AbsoluteLayout m_alTop; 
private Button m_btnAddView, m_btnRemove, saveImage; 
private Context m_context; 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.drag_drop_layout); 

    m_context = this; 
    testImage = new ImageView(m_context); 

    m_prevX = 0; 
    m_prevY = 0; 
    m_imgXB = 50; 
    m_imgYB = 100; 
    m_imgXC = 150; 
    m_imgYC = 100; 

    m_ivImage1 = (ImageView) findViewById(R.id.ddivImage1); 
    m_llTop = (LinearLayout) findViewById(R.id.ddllTop); 
    m_alTop = (AbsoluteLayout) findViewById(R.id.ddalTop); 
    m_btnAddView = (Button) findViewById(R.id.ddbtnAdd); 
    m_btnRemove = (Button) findViewById(R.id.ddbtnRemove); 
    finalImage = (ImageView) findViewById(R.id.finalImage); 
    saveImage = (Button) findViewById(R.id.saveImage); 

    m_ivImage1.setOnTouchListener(m_onTouchListener); 
    m_btnAddView.setOnClickListener(m_onClickListener); 
    m_btnRemove.setOnClickListener(m_onClickListener); 
    saveImage.setOnClickListener(m_onClickListener); 

    //Test code For Merging two images 
    Bitmap bottomImage = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath() + "/android.jpg"); 
    Bitmap topImage = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath() + "/kitkat.jpg"); 

    Bitmap mutableBitmap = bottomImage.copy(Bitmap.Config.ARGB_8888, true); 
    // use the canvas to combine them. 
    // Start with the first in the constructor.. 
    Canvas comboImage = new Canvas(mutableBitmap); 
    // Then draw the second on top of that 
    comboImage.drawBitmap(topImage, 10f, 10f, null); 

    // bottomImage is now a composite of the two. 

    // To write the file out to the SDCard: 
    OutputStream os = null; 
    try 
    { 
     os = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/myNewFileName.jpg"); 
     mutableBitmap.compress(Bitmap.CompressFormat.PNG, 50, os); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    //End of Test Code 

} 

/** 
* Common click listener for clickable controls 
*/ 
OnClickListener m_onClickListener = new OnClickListener() 
{ 

    @Override 
    public void onClick(View p_v) 
    { 
     switch (p_v.getId()) 
     { 
     case R.id.ddbtnAdd: 
      addView(); 
      break; 
     case R.id.ddbtnRemove: 
      removeView(); 
      break; 
     case R.id.saveImage: 
      saveImage(); 
      break; 
     default: 
      break; 
     } 
    } 
}; 

@TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
private void saveImage() 
{ 
    Drawable sourceDrawable = sourceImage.getDrawable(); 
    //    Drawable targetDrawable = targetImage.getDrawable(); 

    finalImage = new ImageView(m_context); 

    if (null != testImage.getBackground()) 
    { 
     //imageview have image 

     Log.d(TAG, "Image is not null in SaveImage"); 
     finalImage.setVisibility(View.VISIBLE); 
     finalImage.setBackgroundDrawable(testImage.getBackground()); 
    } 
    else 
    { 
     //imageview have no image 
     Log.d(TAG, "Image is null in SaveImage"); 
    } 
} 

/** 
* Touch listener for view 
*/ 
OnTouchListener m_onTouchListener = new OnTouchListener() 
{ 

    @Override 
    public boolean onTouch(View p_v, MotionEvent p_event) 
    { 
     switch (p_event.getAction()) 
     { 
     case MotionEvent.ACTION_DOWN: 
     { 
      m_lastTouchX = p_event.getX(); 
      m_lastTouchY = p_event.getY(); 

      break; 
     } 
     case MotionEvent.ACTION_UP: 
     { 
      //It indicates that the pressure on image is released and it is stable now i.e it is not in motion. 
      //Todo Save final image 
      //    saveImage(); 
      break; 
     } 

     case MotionEvent.ACTION_MOVE: 
     { 
      m_dx = p_event.getX() - m_lastTouchX; 
      m_dy = p_event.getY() - m_lastTouchY; 

      m_posX = m_prevX + m_dx; 
      m_posY = m_prevY + m_dy; 

      if (m_posX > 0 && m_posY > 0 && (m_posX + p_v.getWidth()) < m_alTop.getWidth() && (m_posY + p_v.getHeight()) < m_alTop.getHeight()) 
      { 
       p_v.setLayoutParams(new AbsoluteLayout.LayoutParams(p_v.getMeasuredWidth(), p_v.getMeasuredHeight(), (int) m_posX, (int) m_posY)); 

       m_prevX = m_posX; 
       m_prevY = m_posY; 

      } 

      break; 

     } 

     } 
     return true; 
    } 
}; 

View.OnDragListener m_dragListener = new View.OnDragListener() 
{ 
    @Override 
    public boolean onDrag(View view, DragEvent dragEvent) 
    { 
     Log.d(" Drag Event", "Drop Event " + dragEvent.getAction()); 

     if (dragEvent.getAction() == DragEvent.ACTION_DROP) 
     { 
      Log.d(" Drag Event", "Drop Ended "); 
     } 

     return true; 
    } 
}; 

/** 
* Add view dynamically for drag and drop 
*/ 
private void addView() 
{ 
    sourceImage = new ImageView(m_context); 
    targetImage = new ImageView(m_context); 
    TextView m_tv = new TextView(m_context); 
    if (m_counter < 6) 
    { 
     if (m_counter % 2 == 0) 
     { 

      sourceImage.setBackgroundResource(R.drawable.ic_launcher); 

      //m_tv.setText("Hello! Drag Me! "); 
      m_alTop.addView(m_tv, new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT, ((int) m_imgXB), ((int) m_imgYB))); 
      m_alTop.addView(sourceImage, new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT, ((int) m_imgXB), ((int) m_imgYB))); 
     } 
     else 
     { 
      targetImage.setBackgroundResource(android.R.drawable.star_big_on); 
      m_alTop.addView(targetImage, new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT, ((int) m_imgXC), ((int) m_imgYC))); 
     } 
     m_counter++; 
     if (m_counter == 6) m_btnAddView.setEnabled(false); 
    } 
    if (null != sourceImage.getBackground()) 
    { 
     //imageview have image 
     testImage = sourceImage; 
     Log.d(TAG, "Image is not null in addView"); 
    } 
    else 
    { 
     //imageview have no image 
     Log.d(TAG, "Image is null"); 
    } 

    //  sourceImage.setOnTouchListener(m_onTouchListener); 
    targetImage.setOnTouchListener(m_onTouchListener); 
    sourceImage.setOnTouchListener(m_onTouchListener); 
    m_tv.setOnTouchListener(m_onTouchListener); 
} 

public void removeView() 
{ 
    m_counter = 0; 
    m_alTop.removeAllViews(); 
    m_alTop.invalidate(); 
    m_btnAddView.setEnabled(true); 
} 

@Override 
public void onBackPressed() 
{ 
    this.clearView(); 
    super.onBackPressed(); 
} 

@Override 
protected void onDestroy() 
{ 
    this.clearView(); 
    super.onDestroy(); 
} 

/** 
* Clear the views and free memory 
*/ 
public void clearView() 
{ 
    if (m_context != null) m_context = null; 

    if (m_llTop != null) m_llTop = null; 

    if (m_alTop != null) m_alTop = null; 

    if (m_btnAddView != null) m_btnAddView = null; 

    if (m_btnRemove != null) m_btnRemove = null; 

    if (m_ivImage1 != null) m_ivImage1 = null; 
} 

@Override 
public boolean onDrag(View view, DragEvent dragEvent) 
{ 
    Log.d(TAG, "Drop Event " + dragEvent.getAction()); 
    return true; 
} 

这段代码的输出:

正如你所看到的超过Droid的明星。但现在如何从这个图像中保存图像并保存它?

回答

1

请在saveImage()方法试试这个:

try { 
    // Create a new File instance to save the generated image; 
    File file = new File(Environment.getExternalStorageDirectory() 
      .getPath() + "/saved.png"); 
    // Check if File does not exist in the storage; 
    if (!file.exists()) { 
     // Create a physical File; 
     file.createNewFile(); 
    } 
    // Initialize a FileOutputStream to write to the File; 
    FileOutputStream fos = new FileOutputStream(file); 
    // Top edge Y coordinate of the top most child View; 
    int boundTop = m_alTop.getMeasuredHeight(); 
    // Left edge X coordinate of the left most child View; 
    int boundLeft = m_alTop.getMeasuredWidth(); 
    // Bottom edge Y coordinate of the bottom most child View; 
    int boundBottom = 0; 
    // Right edge X coordinate of the right most child View; 
    int boundRight = 0; 
    // Get the total number of child Views present in the Layout; 
    int totalChildren = m_alTop.getChildCount(); 
    // Value to add as padding to the final image; 
    int padding = 20; 
    // Iterate through all the child Views; 
    for(int i = 0; i < totalChildren; i++) { 
     // Get the current child View; 
     View vw = m_alTop.getChildAt(i); 
     // Check if it is higher than the current top edge; 
     if(vw.getTop() < boundTop) { 
      // Update the top edge value; 
      boundTop = vw.getTop(); 
     } 
     // Check if it is more leftwards than the current left edge; 
     if(vw.getLeft() < boundLeft) { 
      // Update the left edge value; 
      boundLeft = vw.getLeft(); 
     } 
     // Check if it is lower than the current bottom edge; 
     if(vw.getBottom() > boundBottom) { 
      // Update the bottom edge value; 
      boundBottom = vw.getBottom(); 
     } 
     // Check if it is more rightwards than the current right edge; 
     if(vw.getRight() > boundRight) { 
      // Update the right edge value; 
      boundRight = vw.getRight(); 
     } 
    } 
// Toast.makeText(this, boundTop + ", " + boundLeft + ", " + boundBottom + ", " + boundRight, Toast.LENGTH_LONG) 
//  .show(); 
    // Calculate the final Bitmap width; 
    int bWidth = padding + boundRight - boundLeft; 
    // Calculate the final Bitmap height; 
    int bHeight = padding + boundBottom - boundTop; 
    // Create a Bitmap Object with the specified width and height; 
    Bitmap bitmap = Bitmap.createBitmap(bWidth, 
      bHeight, Bitmap.Config.ARGB_8888); 
    // Initialize a Canvas to draw to the Bitmap; 
    Canvas canvas = new Canvas(bitmap); 
    // Fill the Bitmap with transparency; 
    canvas.drawColor(Color.TRANSPARENT); 
    /* 
    * Translate the Canvas towards top left direction to compensate for 
    * the blank space between the extreme Views and the edges of the 
    * Layout and also the extra padding. 
    */ 
    canvas.translate(- boundLeft + padding/2, - boundTop + padding/2); 
    // Make the Layout draw its child Views on the Canvas; 
    m_alTop.draw(canvas); 
    // Save the Bitmap to the File instance; 
    bitmap.compress(Bitmap.CompressFormat.PNG, 81, fos); 
    // Flush(Clear) the FileOutputStream; 
    fos.flush(); 
    // Close the FileOutputStream; 
    fos.close(); 
    // Flag the Bitmap for garbage collection; 
    bitmap.recycle(); 
}catch (Exception e) { 
    Toast.makeText(this, "ERROR WHILE SAVING", Toast.LENGTH_LONG) 
      .show(); 
    e.printStackTrace(); 
} 

有在addView()方法,我不得不注释掉使其正常工作添加一个流浪空白TextView

if (m_counter % 2 == 0) { 
    . 
    . 
    // m_alTop.addView(m_tv, new AbsoluteLayout.LayoutParams.... 
    m_alTop.addView(sourceImage, new AbsoluteLayout.LayoutParams.... 

编辑:已更改ConfigRGB_565ARGB_8888

Edit_2015_04_16:现在使用填充将位图裁剪图像保存在位图中,并且还添加了透明背景。

+0

Thanks @electrocrat。这对我很有用。如何使此位图背景透明并在中心绘制位图需要小忙? –

+0

@Deep Shah,请检查我的更新答案。通过**“...在中心绘制位图...”**我假设你只想以一些填充的位图为中心的视图。 – electrocrat

+0

再次感谢它的工作。 –

2

该函数将视图转换为位图。将目标图像传递给以下方法,并将返回其所有子视图的位图。

public static Bitmap getBitmapFromView(View view) { 
    //Define a bitmap with the same size as the view 
    Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888); 
    //Bind a canvas to it 
    Canvas canvas = new Canvas(returnedBitmap); 
    //Get the view's background 
    Drawable bgDrawable =view.getBackground(); 
    if (bgDrawable!=null) 
     //has background drawable, then draw it on the canvas 
     bgDrawable.draw(canvas); 
    else 
     //does not have background drawable, then draw white background on the canvas 
     canvas.drawColor(Color.WHITE); 
    // draw the view on the canvas 
    view.draw(canvas); 
    //return the bitmap 
    return returnedBitmap; 
} 
相关问题