如何合并/覆盖保存其它图像后的图像? [英] How to merge/save image after overlaying other image?

查看:250
本文介绍了如何合并/覆盖保存其它图像后的图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现,其中有两个图像的应用程序。第一张图片是静态的或者更确切地说,说下拉式目标为Android拖放放大器;降的概念和第二图像是拖动。这是可拖动的图像被拖动并放置在其它图象。直到此时应用程序工作得很好,但我是卡在如何保存这个overlayered形象。

I am implementing an application in which there are two images . First image is static or rather say "drop-target" for android "Drag & Drop" concept and second image is "draggable" . An image which is draggable is dragged and placed it over the other image . Till this point application works just fine but i'm stuck on how to save this overlayered image.

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

Here i provide what i've done till now :

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;
}

这code的输出:

正如你所看到的Droid上的明星。但现在如何从本作的图像并保存,因为它是?

As you can see an star over Droid. But now how to make image from this and save as it is ?

推荐答案

请尝试这种在 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();
}

有一只流浪空白的TextView 中,我不得不注释掉此 addView()方法添加正常工作:

There was a stray blank TextView being added in addView() method which I had to comment out for this to work correctly:

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

编辑:修改配置 RGB_565 ARGB_8888

Edit_2015_04_16:立即节省裁剪图像中的位图以填充和还增加了透明背景

Edit_2015_04_16: Now saving cropped image in Bitmap with a padding and also added transparent background.

这篇关于如何合并/覆盖保存其它图像后的图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆