20190521のJavaに関する記事は15件です。

JUnitでモックを利用したテストコード(EasyMock中心)

JUnitでモックを使ったテストについてです。
職場でテストコードを普及させるための記事2回目になります。
EasyMockについてが中心となるので、あまり最近の話ではありません。

実行環境

  • Java 1.8
  • JUnit 4.4
  • EasyMock 2.4
  • Seasar 2.4.46

モックとは

モックオブジェクト(Mock Object)とは、ソフトウェアテスト時、特にテスト駆動開発、ビヘイビア駆動開発における代用の下位モジュールスタブの一種。スタブと比較して、検査対象のモジュール
がその下位モジュールを正しく利用しているかどうかを検証するのに使われる。

モックオブジェクト 出典: フリー百科事典『ウィキペディア(Wikipedia)』

使い方としては、例えば以下のようにHelloJunitというクラスを作成しているとします。
このクラスをテストしようとした際に、もしGreetDaoクラスができていない(あとはDaoで参照しているDBが用意されていないとか)とした場合に、普通にテストしてしまうとエラーになってしまうと思います。

HelloJunit
public class HelloJunit {

    @Binding
    GreetDao greetDao;

    public String sayGreeting() {
        return greetDao.getGreet();
    }

本来はHelloJunitクラスをテストしたいだけなので、依存先(GreetDao)のコードができていなくてもテストできるべきだよねということで、ひとまず動くようにハリボテのクラスを用意して動かせるようにしようよ。というのがモックの役割になります。

どうやってモックを作るのか

以下のような方法があります。

  • モックライブラリを利用
  • モックを作成したいクラスを継承してテスト用に作成する

モックライブラリとしては、MockitoJMockit、そしてEasyMockMockInterceptorなどがあります。

最近ではMockitoがよく使われている印象です。

Seasar2ではEasyMockMockInterceptorがデフォルトで入っています。
いまだにSeasar2を利用しているような環境で新しいライブラリを入れるのは難しいと思いますので、今回はEasyMockで進めたいと思います。

EasyMockを利用したテストコードサンプル

とりあえずコード

プロダクトコードについて上で紹介した内容から少し変更しています。
理由については後ほど説明します。

プロダクトコード
public class HelloJunit {

    GreetDao greetDao;

    public HelloJunit(GreetDao greetDao) {
        this.greetDao = greetDao;
    }

    public String sayGreeting() {
        return greetDao.getGreet();
    }
}

テストコードはこちらです。

テストコード
import static org.easymock.EasyMock.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;
import org.seasar.framework.unit.annotation.EasyMock;
import org.seasar.sastruts.example.dao.GreetDao;

public class HelloJunitTest {

    HelloJunit helloJunit;

    @EasyMock
    GreetDao greetDao;

    @Before
    public void setUp() {
        greetDao = createMock(GreetDao.class);
        helloJunit = new HelloJunit(greetDao);
    }

    @Test
    public void 挨拶を言う() throws Exception {
        // setup(事前準備)
        expect(greetDao.getGreet()).andReturn("Hello");
        replay(greetDao);

        // exercise(実行)
        String actual = helloJunit.sayGreeting();

        // verify(検証)
        String expected = "Hello";
        assertThat(actual, is(expected));
        verify(greetDao);

        // tear down(後処理)
        // 何かあれば・・・
    }
}

なんとなくわかると思いますが解説します。

EasyMockアノテーション

メンバー変数にGreetDaoを用意しているのですが、EasyMockアノテーションがついています。
これをつけることでEasyMockを利用可能になります。

createMock

setUpメソッドではcreateMockメソッドを利用して、greetDaoを作成しています。
ここで作成したgreetDaoをテスト対象メソッドであるhelloJunitのインスタンス生成時に渡してあげることで、モックがセットされることになります。

テストメソッド内のsetup

setup(事前準備)というコメントの中では、expectメソッドを利用しています。
ここがモックの挙動を決める一番重要な部分です。

greetDao.getGreet()がこういう呼び出し方をされた場合、〜を返すよというのを設定しています。
expected()でメソッドの呼び出し方を指定。その後のandReturn()で戻り値を設定します。
今回の場合は、引数なしのgreetDao.getGreet()を呼び出した場合に、"Hello"を返すという設定をしています。

replayというメソッドは直前で設定したモックの挙動を記憶するというイメージです。
expected()を実行したらreplayをするというようにしてください。

exercise

ここではテストをしたいメソッドを実行して、変数に格納しています。
格納する変数はどのような型であってもactualに統一するとわかりやすいと言われています。

verify

ここでは、helloJunit.sayGreeting();の戻り値と期待値を比較しています。
また、verify(greetDao);というのは、setup内で指定したモックの挙動が想定通り呼び出されたかを検証します。
もしhelloJunit.sayGreeting();が1回も呼び出されていなければエラーが返却されます。

tear down

ここはテスト後の後処理を行います。
例えばテストデータをDBに投入していたとした場合、そのデータを削除したりを行います。

EasyMockの利用方法

引数をチェックする

今回はgreetDaoのfindGreetメソッドが想定通りの呼び出され方をしているか確認します。

テスト対象コード
public String sayGreeting() {
    return greetDao.findGreet(1);
}

expect()内に期待しているメソッドの呼び出し方をそのまま書きます。
今回の場合は、findGreetの引数に1が入ることを想定しているので、そのままfindGreet(1)を記載します。

テストコード
@Test
public void 引数テスト() throws Exception {
    // setup(事前準備)
    expect(greetDao.findGreet(1)).andReturn("Hello");
    replay(greetDao);

    // exercise(実行)
    String actual = helloJunit.sayGreeting();

    // verify(検証)
    verify(greetDao);
}

ちなみに、もしfindGreet(2);で呼び出されていた場合には以下のようなエラーが出力されます。

エラーの場合の参考
java.lang.AssertionError: 
  Unexpected method call findGreet(2):
    findGreet(1): expected: 1, actual: 0
    at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:32)
    at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:61)
    at com.sun.proxy.$Proxy4.findGreet(Unknown Source)
    at org.seasar.sastruts.example.service.HelloJunit.sayGreeting(HelloJunit.java:17)
    at org.seasar.sastruts.example.service.HelloJunitTest.引数テスト(HelloJunitTest.java:52)
--以降略--

戻り値をセットして後続処理をテストする

findGreetの戻り値によって分岐を入れてみました。
今回のテストでは、パスタが返却されるパターンをテストしたいと思います。

プロダクションコード
public String sayGreeting() {
    String greet = greetDao.findGreet(1);
    if (greet.contentEquals("Hello")) {
        return "パスタ";
    } else {
        return "ラーメン";
    }
}

戻り値を設定するには、andReturnに戻り値を指定します。
今回の場合は、"Hello"が返却されるようになります。

テストコード
@Test
public void 引数テスト() throws Exception {
    // setup(事前準備)
    expect(greetDao.findGreet(1)).andReturn("Hello");
    replay(greetDao);

    // exercise(実行)
    String actual = helloJunit.sayGreeting();

    // verify(検証)
    String expected = "パスタ";
    assertThat(actual, is(expected));
    verify(greetDao);
}

戻り値をセットして後続処理をテストする

void型のメソッドをテストする方法です。

プロダクションコード(GreetDao)
public interface GreetDao {
    public void insertGreet(String greet);
}
プロダクションコード(HelloJunit)
public String addGreet() {
    greetDao.insertGreet("Good Night");
    return "OK";
}

void型をテストする場合は、テストコードの中で実際にvoidメソッドを実行します。
その後にexpectLastCall()を呼び出します。
これによって、直前のメソッド実行を記憶して検証することができます。

ちなみに同一のvoidメソッドを二回実行している場合には、expectLastCall().times(2);というようにtimes()を付与することで、回数分実行されたかを検証します。

テストコード
@Test
public void voidメソッドをテスト() throws Exception {
    // setup(事前準備)
    greetDao.insertGreet("Good Night");
    expectLastCall();
    replay(greetDao);

    // exercise(実行)
    String actual = helloJunit.sayGreeting();

    // verify(検証)
    verify(greetDao);
}

EasyMockの注意点

EasyMockでは、インターフェースのクラスしかモックすることができません。
もし具象クラスをモックしたい場合は、次に紹介する継承する方法を試してください。

補足:org.easymock.classextension.EasyMock を利用することで具象クラスもテスト可能ですが、古いバージョンのSeasarを利用している場合は入っていない可能性あります。

継承してチェックする

テスト対象のメソッド内で利用しているクラスがインターフェースでなかったり、テストするには不都合があるような場合には、テストのために継承してモッククラスを自分で用意することもあります。

例えば、メソッドで返却されるBeanにequalsメソッドがオーバーライドされておらず、一つ一つのフィールドをチェックするのがめんどくさいような場合は、以下のようにequalsを継承してテストします。

テスト対象のプロダクションコード
public TransferResultDto transfer(String payerAccountId,
                                        String payeeAccountId,
                                        String payerName,
                                        long transferAmount) {

        Balance payerBalance = balanceDao.findByAccountId(payerAccountId);
        if (payerBalance == null)
            throw new BusinessLogicException("残高が取得できません");

        if (transferAmount > payerBalance.amount)
            throw new BusinessLogicException("残高が足りません");

        Balance payeeBalance = balanceDao.findByAccountId(payeeAccountId);
        if (payeeBalance == null)
            throw new BusinessLogicException("振込先口座が存在しません");

        LocalDateTime transferDate = LocalDateTime.now();

        Transfer peyerTransaction = new Transfer();
        peyerTransaction.accountId = payerAccountId;
        peyerTransaction.name = payerBalance.name;
        peyerTransaction.transferAmount = -transferAmount;
        peyerTransaction.transferDate = transferDate;

        Transfer payeeTransaction = new Transfer();
        payeeTransaction.accountId = payeeAccountId;
        payeeTransaction.name = payeeBalance.name;
        payeeTransaction.transferAmount = transferAmount;
        payeeTransaction.transferDate = transferDate;

        transferDao.insertTransfer(peyerTransaction);
        transferDao.insertTransfer(payeeTransaction);
        balanceDao.updateAmount(payerAccountId, -transferAmount);
        balanceDao.updateAmount(payeeAccountId, transferAmount);

        Balance updatedPayerBalance = balanceDao.findByAccountId(payerAccountId);

        return new TransferResultDto(payerAccountId, payeeAccountId,
                                     payerBalance.name, payeeBalance.name,
                                     transferAmount,
                                     updatedPayerBalance.amount);
    }
}
戻り値のBean
public class TransferResultDto {

    private final String payerAccountId;
    private final String payeeAccountId;
    private final String payerName;
    private final String payeeName;
    private final long transferAmount;
    private final long amount;

    public TransferResultDto(String payerAccountId,
                             String payeeAccountId,
                             String payerName,
                             String payeeName,
                             long transferAmount,
                             long amount) {

        this.payerAccountId = payerAccountId;
        this.payeeAccountId = payeeAccountId;
        this.payerName = payerName;
        this.payeeName = payeeName;
        this.transferAmount = transferAmount;
        this.amount = amount;
    }

    public String getPayerAccountId() {
        return payerAccountId;
    }

    public String getPayeeAccountId() {
        return payeeAccountId;
    }

    public String getPayerName() {
        return payerName;
    }

    public String getPayeeName() {
        return payeeName;
    }

    public long getTransferAmount() {
        return transferAmount;
    }

    public long getAmount() {
        return amount;
    }

}

これをテストする場合には、テストクラス内でTransferResultDtoを継承してTransferResultDtoMockクラスを作成します。
このTransferResultDtoMockクラスの中で全てのフィールドを比較するequalsメソッドを用意して、テストする際にはassertThat(actual, is(expected));というように isで比較できるようになります。

今回は、equalsメソッドを書くのがめんどくさいので、lombokを利用して自動生成しました

public class TransferServiceTest {
    @Test
    public void 継承モックを試す() {
        // setup
        TransferResultDtoMock expected = 
                        new TransferResultDtoMock("1", "2",
                                                ACCOUNT1_BEFORE_BALANCE.name, ACCOUNT2_BALANCE.name,
                                                2000, ACCOUNT1_AFTER_BALANCE.amount);

        TransferResultDto transferResultDto = transferService.transfer("1", "2", "田中太郎", 1000);
        TransferResultDtoMock actual = new TransferResultDtoMock(transferResultDto);
        assertThat(actual, is(expected));
    }


    @EqualsAndHashCode(callSuper = true)
    private class TransferResultDtoMock extends TransferResultDto {
        public TransferResultDtoMock(String payerAccountId,
                                     String payeeAccountId,
                                     String payerName,
                                     String payeeName,
                                     long transferAmount,
                                     long amount) {

            super(payerAccountId, payeeAccountId, payerName,
                    payeeName, transferAmount, amount);

        }

        public TransferResultDtoMock(TransferResultDto transferResultDto) {
            super(transferResultDto.getPayerAccountId(),
                  transferResultDto.getPayeeAccountId(),
                  transferResultDto.getPayerName(),
                  transferResultDto.getPayeeName(),
                  transferResultDto.getTransferAmount(),
                  transferResultDto.getAmount());
        }


    }
}

テストコードを書くにあたって意識すべきこと

ビジネスロジックに関する部分は独立した実装にする

最初にHelloJunit内でGreetDaoをDIするロジックを、アノテーションからコンストラクタ型に変更したと思います。
その理由としては、アノテーションで表現する場合、HelloJunitがフレームワーク(Seasar2)に依存する形になってしまうからです。

プロダクトコード
public class HelloJunit {

    GreetDao greetDao;

    public HelloJunit(GreetDao greetDao) {
        this.greetDao = greetDao;
    }

    public String sayGreeting() {
        return greetDao.getGreet();
    }
}

例えば今後Springに移行することになった場合、アノテーションでDIする場合は @ Autowiredを利用することになります。
なので、コンストラクタでDIすることでフレームワークへの変更も用意になります。

また、テストコードという観点からもアノテーションで実現している場合には、クラスの宣言時に@RunWith(Seasar2.class)を指定する必要がありますが、コンストラクタでDIしている場合には、new してあげればテストが簡単にできます。

参考記事

実践クリーンアーキテクチャ

テストが書きやすいコードを書く

テストを行うにあたり、テストが書きやすいコードというのは重要になります。

例えば以下のようなコードは、TimeJunit.getTime()staticメソッドの結果に応じて条件分岐をしているのですが、staticメソッドはモックで置き換えることが難しいです。

staticメソッドを利用している
public class ExampleJunit {
    public String sayGreeting() {
        int term = TimeJunit.getTime();
        switch(term) {
        case 1:
            return "パスタ";
        case 2:
            return "ラーメン";
        default:
            return "ご飯";
        }
    }
}

あとは継承していてスーパークラスのメソッドを利用している場合もテストしにくいコードになります。
例えば古いシステムだとよく使われているようなこんなロジック。

スーパークラス
public abstract class AbstractJunit {
    public String sayGreeting() {
        return this.getMessage();
    }
    abstract protected String getMessage();
}
継承クラス
public class ExampleJunit extends AbstractJunit {
    protected String getMessage() {
        int term = 1;
        switch(term) {
        case 1:
            return "パスタ";
        case 2:
            return "ラーメン";
        default:
            return "ご飯";
        }
    }
}

今回の例であればテスト可能ですが、実際に業務で継承を利用しているようなケースだと、スーパークラスが神様クラス(なんでもロジックを入れる便利クラス)になっていて、スパゲッティソースになっていたりするので、テストでリフレクションとかしなきゃいけなくなってしまうので扱い辛いです。

本当に継承を使うべきか考えて実装しましょう。

参考記事

テストが書きやすいコードは良いコード

その他参考

http://s2container.seasar.org/2.4/ja/easyMock.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaのバージョン確認

・インストールしたJavaのバージョンを確認をしたい時
windowsの場合
コマンドプロンプトを開く
macの場合
ターミナルを開く

「java -version」のコマンドをコピーして貼り付け。
下のように表示されます。

java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

・確認方法
「java version」の直後のダブルクォートで囲まれた部分(1.8.0_131)がバージョンです。
「Java HotSpot(TM) 64-Bit」が64ビット版。64ではない場合は32ビット版です。

記事の掲載理由
環境構築の際に、既にインストールされているJavaが64bitなのか32bitなのか気になったため記載しました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Mean Filter

Goal

Test OpenCV Mean filter.

OpenCV_MeanFilter.java
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

public class OpenCV_MeanFilter {

    static{System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;

    /**
     *  Launch the application.
     */
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_MeanFilter window = new OpenCV_MeanFilter();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_MeanFilter() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize(){
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\baboon.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv 均值濾波器練習");
        frmjavaSwing.setBounds(100, 100, 560, 620);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(5, 60, image.getHeight()+10, image.getWidth()+10);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        JButton btn3 = new JButton("Kernel-Size3");
        btn3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(Convolution(source,3));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btn3.setBounds(10, 10, 114, 23);
        frmjavaSwing.getContentPane().add(btn3);

        JButton btnNewButton = new JButton("Kernel-Size7");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(Convolution(source,7));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnNewButton.setBounds(162, 10, 114, 23);
        frmjavaSwing.getContentPane().add(btnNewButton);

        JButton btn9 = new JButton("Kernel-Size9");
        btn9.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(Convolution(source,9));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btn9.setBounds(316, 10, 114, 23);
        frmjavaSwing.getContentPane().add(btn9);
    }

    public Mat Convolution(Mat source,int kernelSize){
        Mat kernel = Mat.ones(kernelSize,kernelSize, CvType.CV_32F);
        for(int i=0; i<kernel.rows(); i++){
            for(int j=0; j<kernel.cols(); j++){

                double[] tmp = kernel.get(i, j);
                tmp[0]=tmp[0]/(kernelSize * kernelSize);
                kernel.put(i,j, tmp);
            }
        }
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        Imgproc.filter2D(source, destination, -1, kernel);
        return destination;

    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

}
Result

opencv_mean_shift.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Merge Two Images In Any Shape

Goal

Test OpenCV merge two image with ROI.

OpenCV_MergeTwoImgAnyShape.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.List;

public class OpenCV_MergeTwoImgAnyShape {

    public static void main( String[] args )
    {
        try{
            System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
            //大圖(母圖)
            Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\ncku.jpg",Imgcodecs.CV_LOAD_IMAGE_COLOR);

            //小圖(子圖)
            Mat source1 = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\jelly_studio_logo.jpg",Imgcodecs.CV_LOAD_IMAGE_COLOR);
            Mat destination=source.clone();


            // to make the white region transparent
            Mat mask2=new Mat();
            Mat dst=new Mat();


            Imgproc.cvtColor(source1,mask2,Imgproc.COLOR_BGR2GRAY);
            Imgproc.threshold(mask2,mask2,230,255, Imgproc.THRESH_BINARY_INV);
            List<Mat> planes = new ArrayList<Mat>() ;
            List<Mat> result = new ArrayList<Mat>() ;
            Mat result1=new Mat();
            Mat result2=new Mat();
            Mat result3=new Mat();


            Core.split(source1, planes);

            Core.bitwise_and(planes.get(0), mask2, result1);
            Core.bitwise_and(planes.get(1), mask2, result2);
            Core.bitwise_and(planes.get(2), mask2, result3);

            result.add(result1);
            result.add(result2);
            result.add(result3);
            Core.merge(result, dst);
            //以上白色變透明


            //再把小圖copy到大圖
            Rect roi=new Rect(50,50,90,62);//不能比原圖大,及小
            Mat destinationROI = source.submat( roi );
            dst.copyTo( destinationROI , dst);


            Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\merge3.jpg", source);
        }catch (Exception e) {
            System.out.println("error: " + e.getMessage());
        }
    }
}
Result

merge3.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Merge Two Image

Goal

Test OpenCV to merge two images.

OpenCV_MergeTwoImage.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs;

public class OpenCV_MergeTwoImage {

    public static void main( String[] args )
    {
        try{
            System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
            Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\ncku.jpg",Imgcodecs.CV_LOAD_IMAGE_COLOR);
            Mat source1 = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\jelly_studio_logo.jpg",Imgcodecs.CV_LOAD_IMAGE_COLOR);
            Mat destination=source.clone();

            //Imgproc.resize
            Rect roi=new Rect(50,50,90,62);
            Mat destinationROI = source.submat( roi );
            source1.copyTo( destinationROI , source1);

            Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\merge2.jpg", source);
        }catch (Exception e) {
            System.out.println("error: " + e.getMessage());
        }
    }
}
Result

merge2.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Add Broad

Goal

Test OpenCV add broad around a image.

OpenCV_AddBoard.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;

public class OpenCV_AddBoard {
    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;
    /**
     *  Launch the application.
     */
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_AddBoard window = new OpenCV_AddBoard();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    /**
     * Create the application.
     */
    public OpenCV_AddBoard() {
        initialize();
        System.out.println("Core.BORDER_CONSTANT="+Core.BORDER_CONSTANT);
        System.out.println("Core.BORDER_REPLICATE="+Core.BORDER_REPLICATE);
        System.out.println("Core.BORDER_TRANSPARENT="+Core.BORDER_TRANSPARENT);
        System.out.println("Core.BORDER_WRAP="+Core.BORDER_WRAP);
        System.out.println("Core.BORDER_DEFAULT="+Core.BORDER_DEFAULT);
        System.out.println("Core.BORDER_ISOLATED="+Core.BORDER_ISOLATED);
        System.out.println("Core.BORDER_REFLECT="+Core.BORDER_REFLECT);
        System.out.println("Core.BORDER_REFLECT101="+Core.BORDER_REFLECT101);
        System.out.println("Core.BORDER_REFLECT_101="+Core.BORDER_REFLECT_101);
    }
    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("讀取影像至Java Swing視窗");
        frmjavaSwing.setBounds(100, 100, 613, 690);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel showAlphaValue = new JLabel("0");
        showAlphaValue.setBounds(306, 10, 46, 15);
        frmjavaSwing.getContentPane().add(showAlphaValue);

        final JLabel showBetaValue = new JLabel("0");
        showBetaValue.setBounds(306, 43, 46, 15);
        frmjavaSwing.getContentPane().add(showBetaValue);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 68, 585, 578);
        frmjavaSwing.getContentPane().add(lblNewLabel);

        final JSlider slider_beta = new JSlider();
        slider_beta.setValue(0);
        slider_beta.setMaximum(4);
        slider_beta.setBounds(106, 36, 200, 25);
        frmjavaSwing.getContentPane().add(slider_beta);

        final JSlider slider_alpha = new JSlider();
        slider_alpha.setMaximum(5);
        slider_alpha.setValue(0);
        slider_alpha.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                //System.out.println(slider_alpha.getValue());
                showAlphaValue.setText((float)slider_alpha.getValue()/100+"");
                BufferedImage newImage=matToBufferedImage(AddBoard((float)slider_alpha.getValue()/100,slider_beta.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_alpha.setBounds(96, 10, 200, 25);
        frmjavaSwing.getContentPane().add(slider_alpha);

        JLabel lblAlpha = new JLabel("邊框大小");
        lblAlpha.setBounds(10, 20, 76, 15);
        frmjavaSwing.getContentPane().add(lblAlpha);

        JLabel lblBeta = new JLabel("邊框型式");
        lblBeta.setBounds(10, 45, 62, 15);
        frmjavaSwing.getContentPane().add(lblBeta);


        slider_beta.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showBetaValue.setText((float)slider_beta.getValue()+"");
                BufferedImage newImage=matToBufferedImage(AddBoard((float)slider_alpha.getValue()/100,slider_beta.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });

    }
    public Mat AddBoard(float borderSize,int borderType){
        Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        float top;
        float bottom;
        float left;
        float right;
        top=((borderSize*source.rows()));
        bottom=(borderSize*source.rows());
        left=(borderSize*source.cols());
        right=(borderSize*source.cols());
        destination=source;
        Core.copyMakeBorder(source, destination, (int)top, (int)bottom, (int)left, (int)right, borderType);
        return destination;

    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}
Result

opencv_add_broad.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV OpenCV_SalonUseBlurAddWeighted

Goal

Use OpenCV make salon filter.

OpenCV_SalonUseBlurAddWeighted.java
import org.omg.CORBA.FREE_MEM;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.nio.Buffer;

public class OpenCV_SalonUseBlurAddWeighted {

    static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;

    /**
     *   Launch the application.
     */
    public static void main(String[] args){

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try{
                    OpenCV_SalonUseBlurAddWeighted window = new OpenCV_SalonUseBlurAddWeighted();
                    window.frmjavaSwing.setVisible(true);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     *  Create the application.
     */
    public OpenCV_SalonUseBlurAddWeighted(){
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source1 = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");
        final Mat source2 = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");

        BufferedImage image=matToBufferedImage(BlurAndmerge(source1,source2,1,1,1,1));

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv 夢幻沙龍處理練習");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel showAlphaValue = new JLabel("0");
        showAlphaValue.setBounds(260, 10, 29, 15);
        frmjavaSwing.getContentPane().add(showAlphaValue);

        final JLabel showBetaValue = new JLabel("0");
        showBetaValue.setBounds(259, 35, 29, 15);
        frmjavaSwing.getContentPane().add(showBetaValue);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 68, 438, 438);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        final JSlider slider_Blur = new JSlider();
        slider_Blur.setValue(0);
        slider_Blur.setMaximum(101);
        slider_Blur.setBounds(57, 35, 200, 25);
        frmjavaSwing.getContentPane().add(slider_Blur);

        final JSlider slider_Gamma = new JSlider();
        slider_Gamma.setMaximum(200);
        slider_Gamma.setValue(0);
        slider_Gamma.setBounds(290, 35, 115, 25);
        frmjavaSwing.getContentPane().add(slider_Gamma);


        final JSlider slider_Alpha = new JSlider();
        slider_Alpha.setMaximum(20);
        slider_Alpha.setValue(0);
        slider_Alpha.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                //System.out.println(slider_Alpha.getValue()/10);
                showAlphaValue.setText((float)slider_Alpha.getValue()/10+"");
                if(slider_Blur.getValue()%2==0){
                    slider_Blur.setValue(slider_Blur.getValue()+1);
                }
                BufferedImage newImage=matToBufferedImage(BlurAndmerge(source1,source2,(float)slider_Alpha.getValue()/10,1,-slider_Gamma.getValue(),slider_Blur.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_Alpha.setBounds(57, 10, 200, 25);
        frmjavaSwing.getContentPane().add(slider_Alpha);

        JLabel lblAlpha = new JLabel("透明度");
        lblAlpha.setBounds(10, 20, 46, 15);
        frmjavaSwing.getContentPane().add(lblAlpha);

        JLabel lblBetaval = new JLabel("模糊度");
        lblBetaval.setBounds(10, 45, 46, 15);
        frmjavaSwing.getContentPane().add(lblBetaval);

        JLabel lblGamma = new JLabel("明亮度");
        lblGamma.setBounds(290, 10, 46, 15);
        frmjavaSwing.getContentPane().add(lblGamma);

        final JLabel showTypeValue = new JLabel("0");
        showTypeValue.setBounds(415, 35, 36, 15);
        frmjavaSwing.getContentPane().add(showTypeValue);

        slider_Gamma.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showTypeValue.setText(slider_Gamma.getValue()+"");
                BufferedImage newImage=matToBufferedImage(BlurAndmerge(source1,source2,(float)slider_Alpha.getValue()/10,1,-slider_Gamma.getValue(),slider_Blur.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));

            }
        });

        slider_Blur.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                if(slider_Blur.getValue()%2==0){
                    slider_Blur.setValue(slider_Blur.getValue()+1);
                }

                showBetaValue.setText(slider_Blur.getValue()+"");
                BufferedImage newImage=matToBufferedImage(BlurAndmerge(source1,source2,(float)slider_Alpha.getValue()/10,1,-slider_Gamma.getValue(),slider_Blur.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
    }

    public Mat BlurAndmerge(Mat source1,Mat source2,double alpha,double beta,double gamma,int GaussianKernelSize){
        Mat processBlur=new Mat(source1.rows(),source1.cols(),source1.type());
        Mat destination=new Mat(source1.rows(),source1.cols(),source1.type());
        Imgproc.GaussianBlur(source1, processBlur,new Size(GaussianKernelSize,GaussianKernelSize),0,0);
        Core.addWeighted(processBlur, alpha, source2, beta, gamma, destination);
        return destination;

    }


    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

}

Result

opencv_salon_use_blur_add_weighted.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Mosaic

Goal

Make a mosaic image with OpenCV.

OpenCV_Mosaic.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.List;

public class OpenCV_Mosaic {

    public static void main(String[] args){
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        Mat im  = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");

        Imgproc.resize(im,im,new Size(),0.1,0.1,Imgproc.INTER_NEAREST);
        Imgproc.resize(im,im,new Size(),10.0,10.0,Imgproc.INTER_NEAREST);
        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean_mosaic.jpg", im);
    }
}
Result

clean_mosaic.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Concat

Gaol

Test OpenCV concat.

OpenCV_Concat.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

import java.util.ArrayList;
import java.util.List;

public class OpenCV_Concat {

    public static void main(String[] args){
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat im = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\ncku.jpg");
        List<Mat> matList=new ArrayList<Mat>();
        Mat hdst=new Mat();
        Mat vdst=new Mat();
        //3¦¸
        matList.add(im);
        matList.add(im);
        matList.add(im);
        Core.hconcat(matList, hdst);
        Core.vconcat(matList, vdst);

        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\hconcat_ncku.jpg",hdst);
        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\vconcat_ncku.jpg",vdst);
    }
}
Result

vconcat_ncku.jpg

hconcat_ncku.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV color space

Goal

Test OpenCV change color space.

OpenCV_ChangeColorSpace.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

public class OpenCV_ChangeColorSpace {
    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;

    /**
     *  Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_ChangeColorSpace window = new OpenCV_ChangeColorSpace();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_ChangeColorSpace() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread(
                "D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv 顏色空間轉換練習");
        frmjavaSwing.setBounds(100, 100, 560, 620);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(5, 60, image.getHeight()+10, image.getWidth()+10);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        JButton btnRK0 = new JButton("RGB2HLS");
        btnRK0.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(colorSpaceConversion(source,0));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnRK0.setBounds(5, 10, 110, 23);
        frmjavaSwing.getContentPane().add(btnRK0);

        JButton btnK1 = new JButton("RGB2BGR");
        btnK1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(colorSpaceConversion(source,1));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnK1.setBounds(5, 43, 110, 23);
        frmjavaSwing.getContentPane().add(btnK1);

        JButton btnK2 = new JButton("RGB2HSV");
        btnK2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(colorSpaceConversion(source,2));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnK2.setBounds(118, 10, 98, 23);
        frmjavaSwing.getContentPane().add(btnK2);

        JButton btnK3 = new JButton("RGB2Lab");
        btnK3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(colorSpaceConversion(source,3));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnK3.setBounds(118, 43, 98, 23);
        frmjavaSwing.getContentPane().add(btnK3);

        JButton btnK4 = new JButton("RGB2Luv");
        btnK4.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(colorSpaceConversion(source,4));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnK4.setBounds(226, 10, 100, 23);
        frmjavaSwing.getContentPane().add(btnK4);

        JButton btnK5 = new JButton("RGB2YUV");
        btnK5.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(colorSpaceConversion(source,5));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnK5.setBounds(226, 43, 100, 23);
        frmjavaSwing.getContentPane().add(btnK5);

        JButton btnK6 = new JButton("RGB2YCrCb");
        btnK6.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(colorSpaceConversion(source,6));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnK6.setBounds(336, 10, 110, 23);
        frmjavaSwing.getContentPane().add(btnK6);

        JButton btnK7 = new JButton("RGB2XYZ");
        btnK7.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(colorSpaceConversion(source,7));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnK7.setBounds(336, 43, 98, 23);
        frmjavaSwing.getContentPane().add(btnK7);
    }

    public Mat colorSpaceConversion(Mat source,int type){

        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        if (type==0){
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2HLS);
        }else  if (type==1){
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2BGR);
        }else  if (type==2){
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2HSV);
        }else  if (type==3){
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2Lab);
        }else  if (type==4){
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2Luv);
        }else  if (type==5){
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2YUV);
        }else  if (type==6){
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2YCrCb);
        }else  if (type==7){
            Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2XYZ);
        }
        return destination;

    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}
Result

opencv_color_space.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV EqualizeHist For YUV

Goal

Test OpenCV EqualizeHist with YUV channel.

OpenCV_ContrastUseEqualizeHistForYUV.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class OpenCV_ContrastUseEqualizeHistForYUV {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    private JFrame frmjavaSwing;
    double alpha = 2;
    double beta = 50;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_ContrastUseEqualizeHistForYUV window = new OpenCV_ContrastUseEqualizeHistForYUV();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_ContrastUseEqualizeHistForYUV() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");

        BufferedImage image=matToBufferedImage(equalizeHist(source));

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv彩色影像對比練習3");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 10, 438, 455);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);
    }

    public Mat equalizeHist(Mat source){
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        Mat tempYUV=new Mat(source.rows(),source.cols(),source.type());
        Imgproc.cvtColor(source, tempYUV, Imgproc.COLOR_RGB2YUV);
        List<Mat> yuvList = new ArrayList<Mat>(3);
        Core.split(tempYUV, yuvList);
        Imgproc.equalizeHist(yuvList.get(0), yuvList.get(0));
        //Imgproc.equalizeHist(yuvList.get(1), yuvList.get(1));
        //Imgproc.equalizeHist(yuvList.get(2), yuvList.get(2));
        Core.merge(yuvList, destination);
        Imgproc.cvtColor(destination, destination, Imgproc.COLOR_YUV2RGB);
        return destination;
    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}
Result

opencv_contrast_use_equalize_hist_for_yuv.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Use EqualizeHist With Add Weight For RGB

Goal
OpenCV_ContrastUseEqualizeHistWithAddWeightForRGB.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class OpenCV_ContrastUseEqualizeHistWithAddWeightForRGB {

    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;
    double alpha =2;
    double beta = 2;
    double gamma=1;

    /**
     *  Launch the application.
     */
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try{
                    OpenCV_ContrastUseEqualizeHistWithAddWeightForRGB window = new OpenCV_ContrastUseEqualizeHistWithAddWeightForRGB();
                    window.frmjavaSwing.setVisible(true);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     *  Create the application.
     */
    public OpenCV_ContrastUseEqualizeHistWithAddWeightForRGB(){
        init();
    }

    /**
     *  Init the contents of the frame.
     */
    private void init(){
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");

        BufferedImage image=matToBufferedImage(equalizeHist(source));

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv彩色影像對比練習1");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 10, 438, 455);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);
    }

    public Mat equalizeHist(Mat source){
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        Mat source2=new Mat(source.rows(),source.cols(),source.type());
        List<Mat> bgrList = new ArrayList<>(3);
        Core.split(source,  bgrList);
        Imgproc.equalizeHist(bgrList.get(0), bgrList.get(0));
        Imgproc.equalizeHist(bgrList.get(1), bgrList.get(1));
        Imgproc.equalizeHist(bgrList.get(2), bgrList.get(2));
        Core.merge(bgrList, destination);
        Core.addWeighted(source,alpha,source2,beta,gamma,destination);
        return destination;
    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}
Result

opencv_contrast_use_equalizehist_with_add_weight_for_rgb.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OpenCV Contrast Use Equalize Hist For RBG

Goal

Test OpenCV Equalize Hist with split RGB channel then merge to original image.

OpenCV_ContrastUseEqualizeHistForRBG.java
import java.awt.EventQueue;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class OpenCV_ContrastUseEqualizeHistForRBG {

    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;
    double alpha =2;
    double beta = 2;

    /**
     *  Launch the application.
     */
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try{
                    OpenCV_ContrastUseEqualizeHistForRBG window = new OpenCV_ContrastUseEqualizeHistForRBG();
                    window.frmjavaSwing.setVisible(true);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     *  Create the application.
     */
    public OpenCV_ContrastUseEqualizeHistForRBG(){
        init();
    }

    /**
     *  Init the contents of the frame.
     */
    private void init(){
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");

        BufferedImage image=matToBufferedImage(equalizeHist(source));

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv彩色影像對比練習1");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 10, 438, 455);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);
    }

    public Mat equalizeHist(Mat source){
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        List<Mat> bgrList = new ArrayList<>(3);
        Core.split(source,  bgrList);
        Imgproc.equalizeHist(bgrList.get(0), bgrList.get(0));
        Imgproc.equalizeHist(bgrList.get(1), bgrList.get(1));
        Imgproc.equalizeHist(bgrList.get(2), bgrList.get(2));
        Core.merge(bgrList, destination);
        return destination;
    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}

opencv_contrast_use_equalize_hist_for_rgb.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Affine

Goal

Test OpenCV affine.

OpenCV_WarpAffine.java
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;

import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;

public class OpenCV_WarpAffine {

    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}

    private JFrame frmjavaSwing;
    double alpha =2;
    double beta =50;

    /**
     *  Launch the application.
     */
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try{
                    OpenCV_WarpAffine window = new OpenCV_WarpAffine();
                    window.frmjavaSwing.setVisible(true);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }

    public OpenCV_WarpAffine(){
        init();
    }

    /**
     *  Init the contents  of the frame.
     */
    private void init(){
        final Mat src = Imgcodecs.imread(
                "D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");

        BufferedImage image =  matToBufferedImage(src);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("OpenCV 影像扭曲練習");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel showDot1Value = new JLabel("0.1");
        showDot1Value.setBounds(210, 10, 27, 15);
        frmjavaSwing.getContentPane().add(showDot1Value);

        final JLabel showDot2Value = new JLabel("0.1");
        showDot2Value.setBounds(210, 35, 27, 15);
        frmjavaSwing.getContentPane().add(showDot2Value);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 91, 438, 467);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        final JSlider slider_Dot2 = new JSlider();
        slider_Dot2.setMaximum(10);
        slider_Dot2.setValue(0);
        slider_Dot2.setBounds(47, 33, 162, 25);
        frmjavaSwing.getContentPane().add(slider_Dot2);

        final JSlider slider_Dot3 = new JSlider();
        slider_Dot3.setMaximum(10);
        slider_Dot3.setValue(0);

        slider_Dot3.setBounds(47, 56, 162, 25);
        frmjavaSwing.getContentPane().add(slider_Dot3);



        final JSlider slider_Dot1 = new JSlider();
        slider_Dot1.setMaximum(10);
        slider_Dot1.setValue(0);

        slider_Dot1.setBounds(47, 10, 162, 25);
        frmjavaSwing.getContentPane().add(slider_Dot1);

        JLabel lblAlpha = new JLabel("var1");
        lblAlpha.setBounds(10, 20, 46, 15);
        frmjavaSwing.getContentPane().add(lblAlpha);

        JLabel lblBeta = new JLabel("var2");
        lblBeta.setBounds(10, 45, 46, 15);
        frmjavaSwing.getContentPane().add(lblBeta);

        JLabel lblDot = new JLabel("var3");
        lblDot.setBounds(10, 68, 27, 15);
        frmjavaSwing.getContentPane().add(lblDot);


        final JLabel showDot3Value = new JLabel("0.1");
        showDot3Value.setBounds(210, 60, 25, 15);
        frmjavaSwing.getContentPane().add(showDot3Value);

        JLabel lblVar_2 = new JLabel("var6");
        lblVar_2.setBounds(234, 66, 32, 15);
        frmjavaSwing.getContentPane().add(lblVar_2);

        JLabel lblVar_1 = new JLabel("var5");
        lblVar_1.setBounds(234, 43, 32, 15);
        frmjavaSwing.getContentPane().add(lblVar_1);

        JLabel lblVar = new JLabel("var4");
        lblVar.setBounds(234, 18, 32, 15);
        frmjavaSwing.getContentPane().add(lblVar);

        final JSlider slider_Dot4 = new JSlider();
        slider_Dot4.setMaximum(10);

        slider_Dot4.setValue(0);
        slider_Dot4.setBounds(265, 10, 162, 25);
        frmjavaSwing.getContentPane().add(slider_Dot4);

        final JSlider slider_Dot5 = new JSlider();
        slider_Dot5.setMaximum(10);

        slider_Dot5.setValue(0);
        slider_Dot5.setBounds(265, 35, 162, 25);
        frmjavaSwing.getContentPane().add(slider_Dot5);

        final JSlider slider_Dot6 = new JSlider();
        slider_Dot6.setMaximum(10);

        slider_Dot6.setValue(0);
        slider_Dot6.setBounds(265, 56, 162, 25);
        frmjavaSwing.getContentPane().add(slider_Dot6);

        final JLabel showDot4Value = new JLabel("0.1");
        showDot4Value.setBounds(437, 10, 27, 15);
        frmjavaSwing.getContentPane().add(showDot4Value);

        final JLabel showDot5Value = new JLabel("0.1");
        showDot5Value.setBounds(437, 35, 27, 15);
        frmjavaSwing.getContentPane().add(showDot5Value);

        final JLabel showDot6Value = new JLabel("0.1");
        showDot6Value.setBounds(437, 56, 27, 15);
        frmjavaSwing.getContentPane().add(showDot6Value);
        slider_Dot1.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                //System.out.println(slider_alpha.getValue());
                showDot1Value.setText((float)slider_Dot1.getValue()/10+"");
                BufferedImage newImage=matToBufferedImage(wrap(src,slider_Dot1.getValue(),(float)slider_Dot2.getValue()/10,(float)slider_Dot3.getValue()/10,(float)slider_Dot4.getValue()/10,(float)slider_Dot5.getValue()/10,(float)slider_Dot6.getValue()/10));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_Dot3.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showDot3Value.setText((float)slider_Dot3.getValue()/10+"");
                BufferedImage newImage=matToBufferedImage(wrap(src,slider_Dot1.getValue(),(float)slider_Dot2.getValue()/10,(float)slider_Dot3.getValue()/10,(float)slider_Dot4.getValue()/10,(float)slider_Dot5.getValue()/10,(float)slider_Dot6.getValue()/10));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });

        slider_Dot2.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showDot2Value.setText((float)slider_Dot2.getValue()/10+"");
                BufferedImage newImage=matToBufferedImage(wrap(src,slider_Dot1.getValue(),(float)slider_Dot2.getValue()/10,(float)slider_Dot3.getValue()/10,(float)slider_Dot4.getValue()/10,(float)slider_Dot5.getValue()/10,(float)slider_Dot6.getValue()/10));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_Dot4.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showDot4Value.setText((float)slider_Dot4.getValue()/10+"");
                BufferedImage newImage=matToBufferedImage(wrap(src,slider_Dot1.getValue(),(float)slider_Dot2.getValue()/10,(float)slider_Dot3.getValue()/10,(float)slider_Dot4.getValue()/10,(float)slider_Dot5.getValue()/10,(float)slider_Dot6.getValue()/10));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_Dot5.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showDot5Value.setText((float)slider_Dot5.getValue()/10+"");
                BufferedImage newImage=matToBufferedImage(wrap(src,slider_Dot1.getValue(),(float)slider_Dot2.getValue()/10,(float)slider_Dot3.getValue()/10,(float)slider_Dot4.getValue()/10,(float)slider_Dot5.getValue()/10,(float)slider_Dot6.getValue()/10));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_Dot6.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showDot6Value.setText((float)slider_Dot6.getValue()/10+"");
                BufferedImage newImage=matToBufferedImage(wrap(src,slider_Dot1.getValue(),(float)slider_Dot2.getValue()/10,(float)slider_Dot3.getValue()/10,(float)slider_Dot4.getValue()/10,(float)slider_Dot5.getValue()/10,(float)slider_Dot6.getValue()/10));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });

    }


    public Mat wrap(Mat source,double dot1,double dot2,double dot3,double dot4,double dot5,double dot6){
        Mat wrapMat=new Mat(2,3, CvType.CV_32FC1);
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        MatOfPoint2f srcTri=new MatOfPoint2f();

        MatOfPoint2f dstTri=new MatOfPoint2f();

        Point[] srcPoints=new Point[3];
        srcPoints[0]=new Point(0,0);
        srcPoints[1]=new Point(source.cols()-1,0);
        srcPoints[2]=new Point(0,source.rows()-1);

        srcTri.fromArray(srcPoints);

        Point[] dstPoints=new Point[3];
        dstPoints[0]=new Point(source.cols()*dot1,source.rows()*dot2);
        dstPoints[1]=new Point(source.cols()*dot3,source.rows()*dot4);
        dstPoints[2]=new Point(source.cols()*dot5,source.rows()*dot6);

        dstTri.fromArray(dstPoints);

        wrapMat=Imgproc.getAffineTransform(srcTri, dstTri);

        Imgproc.warpAffine(source, destination, wrapMat, destination.size());

        return destination;

    }


    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

}
Result

opencv_wrap_affine.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WebViewとネイティブのメリットデメリット

App内で動作する簡易ブラウザ(WebView)と通信からUIまでアプリ内で完結するネイティブアプリのメリットデメリットをまとめてみました。

■WebViewのメリット・デメリット

メリット

  • コストが安い
    Web上にコンテンツがあり、それを流用したい場合、新規で開発することなく同じコンテンツを表示できます。

  • アプリストアへの申請・審査の不要
    ネイティブアプリの申請や審査が不要になります。
    ※ただし、部分的なWebView表示の場合ネイティブと変わらないので審査は必要です。

  • アプリアップデートの不要
    アプリの保守をする必要がないため、アプリ自体のアップデートがありません。
    ※仕様が変更された時は、アプリの動作を変更する可能性があるため、一概ではないです。

デメリット

  • 課金ができない
    Apple Store審査ガイドラインの規約違反になり、リジェクトされる恐れがあります。
    ※Webブラウザでの課金は可能(リンクをブラウザへ飛ばす必要あり)
    引用:Apple Store審査ガイドライン:3.1.1 App内課金

  • レスポンシブ対応
    画面解像度に応じたUI設計の対応が必要。
    Webの表示をそのまま、アプリに適応させると表示崩れが起こる可能性がある。

  • 脆弱性

    1. 自社以外の外部アクセス

      URL直打ちで、自社ではないサイトにアクセスできる場合、悪用される恐れがある。
      外部アクセスできるサイトに制限を設ける必要がある。

    2. 端末内のファイルストリームにアクセスできる

      「file://」で始まるURI(※URLではない)でアクセスすることで、端末内部のファイルにアクセスすることができる。
      アクセスログからユーザー情報が漏洩されてしまう。

    3. iOSは、Cookieを保存しない

      アプリが終了するとCookieが消えるので、永続化する必要がある

    4. XSSの恐れ

      攻撃スクリプトを入力できてしまう。
      サニタイジング(無害化)する必要がある。

  • 通信エラー場合の表示
    通信エラー場合のWebView画面を表示する前に、レスポンスチェックを行い、ネイティブの別画面を表示させる。
    WebViewは通信した結果の表示なので、真っ白になったり、URLエラーになったりしてUI的に作りが悪い。

  • 環境によっては表示が遅い
    Web通信が伴うため、通信環境によっては表示が遅い場合があります。

  • 導線が不可能
    WebViewの誘導はできない。
    alt

■ネイティブ画面のメリット・デメリット

メリット

  • Webではできない画面設計・操作設計ができる
    アプリ内のUIを使用するため、自由に画面設計を行うことが可能

  • 導線設計が可能
    アプリに誘導できる

  • セキュリティ
    URL直打ちではないため、外部のサイトへアクセスさせることはないです。

デメリット

  • コストが高い
    iOS / Androidの開発者が必要
    開発言語が異なるため、それぞれの開発者が必要

  • アプリストアへの申請・審査
    ネイティブアプリの申請や審査が必要です。

  • アプリアップデートが必要
    保守でアプリ修正があった場合は、アップデートが必要

  • 課金
    App内課金を(30%)手数料(30%)が発生する

引用

https://appbu.jp/webapps-nativeapps
https://ja.developer.box.com/docs/android-security-guidelines
https://appkitbox.com/knowledge/android/20130819-84
https://teratail.com/questions/100872
https://mexess.blog/2018/08/03/post-304/
https://qiita.com/noboru_i/items/240ffcb2036f3b5cbc3b
https://qiita.com/noboru_i/items/bc39d95638e9e55437fa#cookie%E3%81%AE%E8%A8%AD%E5%AE%9A
https://qiita.com/i_nak/items/be0fac91bdc68aa165db
https://backapp.co.jp/blog/11594/
https://support.ebis.ne.jp/search_service/15033/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む