Tuesday 15 March 2016

HB Blog 106: Superimposition Overlay Effect On Image Programmatically.

In graphics, superimposition is the placement of an image or video on top of an already-existing image or video, usually to add to the overall image effect, but also sometimes to conceal something (such as when a different face is superimposed over the original face in a photograph).

Here, In this post, I would like to show a simple way to create this effect in an Android application programmatically. We need two images that are suppose to be overlay on each other say, ImageView1 and ImageView2. To achieve this we need to create a blank canvas, on which both the bitmap images are to drawn, with the specific co-ordinates depending on the drag event of the user. So that the user can decide the position at which ImageView2 is to be overlay on ImageView1 as shown below. Finally, we can enjoy the superimposition overlay effect on an image.
Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//MainActivity.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package com.example.harshalbenake.imposeimage;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.net.Uri;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.soundcloud.android.crop.Crop;

import java.io.File;


public class MainActivity extends Activity {

    private ImageView resultImage;
    private ImageView imageView1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        resultImage = (ImageView) findViewById(R.id.imageView3);
        imageView1 = (ImageView) findViewById(R.id.imageView1);
        ImageView imageView2 = (ImageView) findViewById(R.id.imageView2);
        Button button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                imageView1.setImageDrawable(null);
                Crop.pickImage(MainActivity.this);
            }
        });

        imageView1.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
                view.startDrag(null, shadowBuilder, view, 0);
                return true;
            }
        });

        imageView2.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View view, DragEvent motionEvent) {
                if (motionEvent.getAction() == DragEvent.ACTION_DROP) {
                    float left = motionEvent.getX();
                    float top = motionEvent.getY();
                    Bitmap firstImage = BitmapFactory.decodeResource(getResources(), R.drawable.proof);
                    imageView1.destroyDrawingCache();
                    imageView1.buildDrawingCache();
                    Bitmap secondImage = imageView1.getDrawingCache();
                    Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
                    Canvas canvas = new Canvas(result);
                    canvas.drawBitmap(firstImage, 0f, 0f, null);
                    canvas.drawBitmap(secondImage, left - 130, top - 60, null);
                    resultImage.setImageBitmap(result);
                }
                return true;
            }
        });

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println(requestCode + " resultCode: " + resultCode);
        if (requestCode == Crop.REQUEST_PICK && resultCode == RESULT_OK) {
            Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
            Crop.of(data.getData(), destination).withAspect(400, 200).start(this);
        } else if (requestCode == Crop.REQUEST_CROP) {
            if (resultCode == RESULT_OK) {
                imageView1.setImageURI(Crop.getOutput(data));
            } else if (resultCode == Crop.RESULT_ERROR) {
                System.out.println(Crop.getError(data).getMessage());
            }
        }
    }
}

Tuesday 1 March 2016

HB Blog 105: Overview Of Build Automation Tools.

Build automation is the process of automating the creation of a software build and the associated processes including: compiling computer source code into binary code, packaging binary code, and running automated tests.

Basically, a build automation was accomplished through makefiles. A makefile is a file that contains a set of directives used with the make build automation tool. Build automation tool are divided into 2 categories namely,
  1. Build automation utility: - Whose primary purpose is to generate build artifacts through activities like compiling and linking the source code.
  2. Build automation servers: - These are general web based tools that execute build automation utilities on a scheduled or triggered basis; a continuous integration server is a type of build automation server. 
There are various tools that automates the process of compiling computer source code into binary code based on creation of make file.
Make-based tools such as GNU make, make, mk, etc.
Non-Make-based tools such as Apache Ant, Apache Maven, Gradle, etc.
Earlier, we used to use Eclipse for our Android development where, we used dx, aapt, etc. tools for Apk creation. Now, have you ever wondered why the res folder is in the same directory as your src folder? This is where the build system enters the picture. The build system automatically takes all the source files (.java or .xml), then applies the appropriate tool (e.g. takes java class files and converts them to dex files), and groups all of them into one compressed file, our beloved APK. This build system uses some conventions: an example of one is to specify the directory containing the source files (in Eclipse it is \src folder) or resources files (in Eclipse it is \res folder). Now, in order to automate all these tasks, there has to be a script; you can write your own build system using shell scripting in linux or batch files syntax in windows.

Gradle is another build system that takes the best features from other build systems and combines them into one. It is improved based off of their shortcomings. It is a JVM based build system, what that means is that you can write your own script in Java, which Android Studio makes use of. One more thing about gradle is that it is a plugin based system. This means if you have your own programming language and you want to automate the task of building some package (output like a JAR for Java) from sources then you can write a complete plugin in Java or Groovy, and distribute it to rest of world.

Have a look on few code snippets,

//build.gradle 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.example.user.myapplication"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
}