如何编辑图像中像素的位图
how to edit a bitmap of the pixels in an image
我写了一个隐写算法,但是需要很长时间才能完成。这是因为我创建了一个新的位图实例 BitmapStegan
,并且我从我的旧位图 bitmap
中提取了每个像素。无论我修改与否,我都必须在新的位图对象中设置它。因此,我最终循环遍历了所有像素,即使我只需要编辑其中的几个像素。
我该如何解决这个问题?
Bitmap BitmapStegan = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
for(int i=0; i<bitmap.getWidth(); i++){
for(int j=0; j<bitmap.getHeight(); j++){
int pixel=bitmap.getPixel(i, j);
int red= Color.red(pixel);
int green=Color.green(pixel);
int blue=Color.blue(pixel);
if (NumberBitsInMessage>0) {
/*
I put here my bit to red and greed and blue with LSB method
*/
}
BitmapStegan.setPixel(i, j, Color.argb(Color.alpha(pixel), red, green, blue));
}
}
imageView.setImageBitmap(BitmapStegan);
首先,您真的需要原始图像的副本吗?如果是,因为要比较原始图像和隐写图像之间的统计差异,所以要create a copy of your bitmap。这样,您可以一次性创建所有像素,速度更快。如果不需要副本,只需将更改直接应用于原始图像对象即可。无论哪种方式,您只需要修改一张图像,从现在开始我将其称为 image
.
现在,关于如何迭代仅足够的像素以进行嵌入,您有两种选择。要么对图像的行和列使用循环并在嵌入整个秘密后打破它们,要么为 NumberBitsInMessage
创建一个计数器并在嵌入位时显式更改像素坐标。
1。打破循环
embedding:
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
if (NumberBitsInMessage == 0) {
break embedding;
}
int pixel = image.getPixel(i, j);
int red = Color.red(pixel);
int green = Color.green(pixel);
int blue = Color.blue(pixel);
/*
modify pixel logic here
*/
image.setPixel(i, j, Color.argb(Color.alpha(pixel), red, green, blue));
}
}
2。嵌入位计数器
int width = 0;
int height = 0;
int maxHeight = image.getHeight();
for (int embeddedBits = 0; embeddedBits < NumberBitsInMessage; ) {
int pixel = image.getPixel(width, height);
int red = Color.red(pixel);
int green = Color.green(pixel);
int blue = Color.blue(pixel);
/*
modify pixel logic here
don't forget to increase `embeddedBits` for each colour you modify
*/
image.setPixel(width, height, Color.argb(Color.alpha(pixel), red, green, blue));
height++;
if (height == maxHeight) {
width++;
height = 0;
}
}
我写了一个隐写算法,但是需要很长时间才能完成。这是因为我创建了一个新的位图实例 BitmapStegan
,并且我从我的旧位图 bitmap
中提取了每个像素。无论我修改与否,我都必须在新的位图对象中设置它。因此,我最终循环遍历了所有像素,即使我只需要编辑其中的几个像素。
我该如何解决这个问题?
Bitmap BitmapStegan = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
for(int i=0; i<bitmap.getWidth(); i++){
for(int j=0; j<bitmap.getHeight(); j++){
int pixel=bitmap.getPixel(i, j);
int red= Color.red(pixel);
int green=Color.green(pixel);
int blue=Color.blue(pixel);
if (NumberBitsInMessage>0) {
/*
I put here my bit to red and greed and blue with LSB method
*/
}
BitmapStegan.setPixel(i, j, Color.argb(Color.alpha(pixel), red, green, blue));
}
}
imageView.setImageBitmap(BitmapStegan);
首先,您真的需要原始图像的副本吗?如果是,因为要比较原始图像和隐写图像之间的统计差异,所以要create a copy of your bitmap。这样,您可以一次性创建所有像素,速度更快。如果不需要副本,只需将更改直接应用于原始图像对象即可。无论哪种方式,您只需要修改一张图像,从现在开始我将其称为 image
.
现在,关于如何迭代仅足够的像素以进行嵌入,您有两种选择。要么对图像的行和列使用循环并在嵌入整个秘密后打破它们,要么为 NumberBitsInMessage
创建一个计数器并在嵌入位时显式更改像素坐标。
1。打破循环
embedding:
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
if (NumberBitsInMessage == 0) {
break embedding;
}
int pixel = image.getPixel(i, j);
int red = Color.red(pixel);
int green = Color.green(pixel);
int blue = Color.blue(pixel);
/*
modify pixel logic here
*/
image.setPixel(i, j, Color.argb(Color.alpha(pixel), red, green, blue));
}
}
2。嵌入位计数器
int width = 0;
int height = 0;
int maxHeight = image.getHeight();
for (int embeddedBits = 0; embeddedBits < NumberBitsInMessage; ) {
int pixel = image.getPixel(width, height);
int red = Color.red(pixel);
int green = Color.green(pixel);
int blue = Color.blue(pixel);
/*
modify pixel logic here
don't forget to increase `embeddedBits` for each colour you modify
*/
image.setPixel(width, height, Color.argb(Color.alpha(pixel), red, green, blue));
height++;
if (height == maxHeight) {
width++;
height = 0;
}
}