3

私は現在、クラスプロジェクトとしてsteganogrpahyandroidアプリに取り組んでいます。画像を別の画像でエンコードし、エンコードされたビットマップを返すオブジェクトを作成しました。このコードは別のスレッドで実行されます。

new Thread(new Runnable()  
{  
   public void run()  
    {  
        Bitmap encoded_image = null;  
        Encryptor encryptor = new Encryptor();  
        encoded_image = encryptor.encode_image_in_image(  
            image_location,message_image_location);  
    }  
}).start();

ビットマップをエンコードした後、ビットマップをpng画像として保存するために作成したファイルブラウザアクティビティにビットマップを渡していました。この方法は小さい画像に対しては機能しますが、大きい画像がエンコードされてサブアクティビティに渡されると、アプリケーションはフリーズしてメインアクティビティに戻ります。

private void pass_image_to_file_browser( Bitmap image )
{
    Intent intent = new Intent(Encrypt.this,FileBrowser.class);
    intent.putExtra( Intent.EXTRA_STREAM, image );
    startActivity( intent );
}

@Override
 public void onCreate(Bundle savedInstanceState) 
 {
    super.onCreate(savedInstanceState);
    Bundle bundle = this.getIntent().getExtras();
    Bitmap image = bundle.getParacable(Intent.EXTRA_STREAM);
 }

インテントを使用してアクティビティ間で送信するには大きなビットマップが大きすぎると想定していたため、画像を一時的な場所に保存し、画像の場所をサブアクティビティに渡すことにしました。次に、ユーザーが指定したpng画像を保存し、一時画像ファイルを削除します。

private void save_bitmap( Bitmap image, String location )
{
    FileOutputStream fileOutputStream = new FileOutputStream(location);
    BufferedOutputStream buffered_output_stream = new 
        BufferOutputStream(fileOutputStream);
    image.compress(CompressFormat.PNG, 0, buffered_output_stream);
    buffered_output_stream.flush();
    buffered_output_stream.close();
}

これにより、あるアクティビティから別のアクティビティに大きなビットマップを送信するという問題は解決されますが、私が解決できなかった新しい問題が発生しました。ファイルの場所をサブアクティビティに渡す前に保存された一時的な画像と、ファイルブラウザを使用して画像を再保存した後の画像ファイルの両方で、色がわずかに変更されています。この色の変化は肉眼では認識できませんが、画像をデコードするときに多くの問題が発生します。Bitmap.ConfigがARGB_8888からARGB_4444またはRGB_565に変更されていると思ったのですが、デバッグ後はそうではありませんでした。ビットマップはARGB_8888としてインスタンス化され、ARGB_8888ビットマップとして保存され、その間で変更されることはありません。ビットマップ全体をファイルブラウザアクティビティに渡し、両方の場所でビットマップをまったく同じように保存している場合でも、コードは機能します。私は他に何がこれを引き起こしているのかについては何も考えていません。他に何が問題を引き起こしている可能性があるかについての提案を探しています。申し訳ありませんが、どちらの場合も出力に画像を投稿するつもりでしたが、スタックオーバーフローでは評判レベルに達しませんでした。ありがとうございます。

4

2 に答える 2

7

さて、スレッドとビットマップをエンコードするために使用していたアルゴリズムについて心配して長い時間を無駄にした後、問題は少し単純になりました。使用していたメッセージでエンコードされる画像ファイルをデバッグしてoptions.inPreferredConfig = Config.ARGB_8888;いる間、デバッグ中に、これがRGB_565に変更されていないことを確認していました。ビットマップオブジェクトはARBG_8888としてロードされましたが、画像ファイルにはアルファチャネルが含まれていなかったため、ビットマップにアルファレベルのバイトがあり、ピクセルのアルファバイトを編集できるようになりました。Bitmap.setPixel( x, y, color)ビットマップオブジェクトは、アルファ値が設定されていることを認識しませんでした。オブジェクトがアルファチャネルがないと考えたため、RGB_565に圧縮されたビットマップを圧縮する場合。どういうわけか、この問題は、ビットマップをサブアクティビティに渡し、それを解析することで解決されました。オブジェクトが再作成されたときに、設定したアルファ値が認識されたと思います。ビットマップをサブアクティビティに渡さずに問題を解決するには、ファイルからビットマップをデコードした後にアルファチャネルを追加する必要があります。私はここでそうするための関数を見つけました。

private Bitmap adjustOpacity( Bitmap bitmap )
{
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Bitmap dest = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    dest.setPixels(pixels, 0, width, 0, 0, width, height);
    return dest;
} 

もっと効率的な方法があるかどうかわかりません

于 2011-03-01T20:49:50.660 に答える
3

私のように、それにつまずいた人は、PNGで書き出すと、なぜビットナップの色が変わるのか疑問に思います。アルファチャネル値がある場合、bitmap.compress(PNG、100、fileout)を呼び出す前にbitmap.setPreMultiplied(false)を使用すると、画像の色が保持されることがわかりました。Setpremultipliedは、ディスクに書き込まれたピクセルがアルファチャネルで乗算されるのを防ぎ、異なるピクセルカラー値を生成します。

于 2019-12-18T20:02:49.857 に答える