- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我仍然无法访问位图图像的颜色位。问题是,将位图的内容保存到缓冲区后,我不知道:
从哪里开始循环(如果我从 0 开始,我认为它会清除标题)?
如何访问字节并进行更改(将 BMP 中的颜色转换为输出中所需的颜色)?
以及,如何将缓冲区插入到新的位图文件中?
我要修改的所有图像都有可被 4 整除的行(当特定字节填充时我必须插入 0)和每像素 24 位。即使是很少的提示,我们也将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "bmp_header.h"
int main(void)
{
FILE *f;
f = fopen("captcha.bmp","rb");
if ((f = fopen("captcha.bmp", "rb")) == NULL)
{
printf("Error opening file %s.\n", "captcha.bmp");
exit(1);
}
fread(&BMP_header,sizeof(BMP_header),1,f);
fread(&BMP_info_header,sizeof(BMP_info_header),1,f);
fseek(f,BMP_header.imageDataOffset,SEEK_SET);
int rows = (BMP_info_header.bitPix * BMP_info_header.width + 31 ) /32 * 4 ;
char *PixelArray =malloc( rows * abs(BMP_info_header.height)*sizeof(char));
int i;
for( i =sizeof(BMP_header)+sizeof(BMP_info_header); i<=(rows * abs(BMP_info_header.height))-2;i+=3)
{
PixelArray[i]=255; // just a random value to test if this makese any sense
PixelArray[i+1]=255;
PixelArray[i+2]=255;
}
return 0;
}
并且,这是bmp_header.h
的内容:
#pragma pack(1)
struct bmp_fileheader
{
unsigned char fileMarker1; /* 'B' */
unsigned char fileMarker2; /* 'M' */
unsigned int bfSize; /* File's size */
unsigned short unused1;
unsigned short unused2;
unsigned int imageDataOffset; /* Offset to the start of image data */
}BMP_header,BMP_header_out;
struct bmp_infoheader
{
unsigned int biSize; /* Size of the info header - 40 bytes */
signed int width; /* Width of the image */
signed int height; /* Height of the image */
unsigned short planes;
unsigned short bitPix;
unsigned int biCompression;
unsigned int biSizeImage; /* Size of the image data */
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
}BMP_info_header,BMP_info_header_out;
#pragma pack()
最佳答案
好吧,我写了一些代码来写出一个完全黑色的位图文件,它具有旧位图文件的原始尺寸。
这不适用于所有类型的位图。例如,16 色位图在信息头后有一个调色板,我的程序没有考虑到这一点。每像素的位数也需要被 8 整除。如果满足这些先决条件,我相信它们在 24 位位图中,那么这个程序应该可以工作。
这里的主要代码在getNewImageData
中。我们使用维基百科使用的相同公式计算图像的行大小 - 它计算所需的位,然后将其填充为四字节的倍数,然后将位转换为字节。然后我们将所有像素阵列内存设置为零(主要是我对在填充字节中保留值感到疑惑)。然后我们沿着每一行运行并编辑每个像素。最里面的 for 循环
对应于每个像素。通过中间 for 循环
的一次迭代写入一个像素。
显然,您可以修改此代码以将像素数据读入分配的内存部分,然后在适当的位置编辑像素数据,然后再将其写回。此示例代码不读取输入像素数据,只是写出与输入文件相同尺寸的黑色位图。
编辑:我想我应该提一下你做错了什么。
fopen
,在内存中某处留下了一个打开的文件指针。 rows
应该重命名为 rowSize
,因为它是一行像素的大小(以字节为单位)PixelArray
未被释放。for 循环
从一个偏移量(两个 header 的大小)开始,然后以像素数据的大小为界。 for 循环
应该从 0 开始并达到像素数据的大小(除非您在执行此操作时正在读取像素数据......您可能不应该这样做)。 for 循环
尝试一次写入所有像素数据,但没有考虑到每行末尾有 0 到 31 位填充的事实像素(我的程序假定填充仅为 0、8、16 或 24 位)。代码如下:
#include <stdio.h>
#include "bmp_header.h"
#include <stdlib.h>
int readBitmapHeaders(char* fileLocation, bmp_fileheader* fileheader, bmp_infoheader* infoheader)
{
FILE* f;
f = fopen(fileLocation, "rb");
if (!f)
{
printf("Error opening file %s.\n", fileLocation);
return 1;
}
fread(fileheader, sizeof(bmp_fileheader), 1, f);
fread(infoheader, sizeof(bmp_infoheader), 1, f);
fclose(f);
return 0;
}
int writeBitmap(char* fileName, bmp_fileheader* fileheader, bmp_infoheader* infoheader, char* pixelArray, size_t pixelArraySize)
{
FILE* out;
out = fopen(fileName, "wb");
if (!out)
{
printf("Error opening file %s.\n", fileName);
return 1;
}
fwrite(fileheader, sizeof(bmp_fileheader), 1, out);
fwrite(infoheader, sizeof(bmp_infoheader), 1, out);
fwrite(pixelArray, pixelArraySize, 1, out);
fclose(out);
return 0;
}
char* getNewImageData(bmp_infoheader* infoheader, size_t* imageSize)
{
//rowsize is padded to 4 bytes
size_t rowSize = (infoheader->bitPix * infoheader->width + 31) / 32 * 4;
size_t pixelArraySize = rowSize * abs(infoheader->height);
char* pixelArray = (char*)malloc(pixelArraySize);
if (!pixelArray)
{
return NULL;
}
memset(pixelArray, 0, pixelArraySize);
size_t bytesPerPixel = infoheader->bitPix / 8;
for (int i = 0; i < infoheader->height; i++)
{
for (int j = 0; j < infoheader->width; j++)
{
size_t offset = rowSize * i + bytesPerPixel * j;
for (size_t k = 0; k < bytesPerPixel; k++)
{
pixelArray[offset + k] = 0;
}
}
}
if (imageSize)
{
*imageSize = pixelArraySize;
}
return pixelArray;
}
int main()
{
char* fileLocation = "test.bmp";
bmp_fileheader header;
bmp_infoheader infoheader;
int readResult = readBitmapHeaders(fileLocation, &header, &infoheader);
if (readResult)
{
return readResult;
}
size_t pixelArraySize;
char* pixelArray = getNewImageData(&infoheader, &pixelArraySize);
if (!pixelArray)
{
printf("%s", "Failed to create the new image data. Exiting with fatal error.\n");
return 1;
}
char* outFile = "out.bmp";
int writeResult = writeBitmap(outFile, &header, &infoheader, pixelArray, pixelArraySize);
free(pixelArray);
return writeResult;
}
我稍微更改了位图头文件以对结构进行 typedef 并使生活更轻松(至少对我而言):
#pragma once
#pragma pack(1)
typedef struct _bmp_fileheader
{
unsigned char fileMarker1; /* 'B' */
unsigned char fileMarker2; /* 'M' */
unsigned int bfSize; /* File's size */
unsigned short unused1;
unsigned short unused2;
unsigned int imageDataOffset; /* Offset to the start of image data */
} bmp_fileheader;
typedef struct _bmp_infoheader
{
unsigned int biSize; /* Size of the info header - 40 bytes */
signed int width; /* Width of the image */
signed int height; /* Height of the image */
unsigned short planes;
unsigned short bitPix;
unsigned int biCompression;
unsigned int biSizeImage; /* Size of the image data */
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} bmp_infoheader;
#pragma pack()
关于c - 位图颜色 - C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34465329/
我想填充 3D 等高线图 (contour3(X,Y,Z)),就像 2D 等高线填充图 (contourf(X,Y,Z))。但我无法弄清楚如何实现这一目标。 contour3 和 surf 的组合不是
我有一个 c3.js 折线图,表示 2 个值的演变。我需要折线图的工具提示是饼图(工具提示 = 另一个 c3.js 图形)。 这是我成功的: http://jsfiddle.net/owhxgaqm/
我有具有结构的 Pandas 数据框: A B 0 1 1 1 2 1 2 3 4 3 3 7 4 6 8 如何生成 Seaborn Violin 图,每列作为其自己的单独
我正在使用 D3DXSPRITE 方法将我的 map 图 block 绘制到屏幕上,我刚刚添加了一个缩放功能,当您按住向上箭头时会放大,但注意到您现在可以看到图 block 之间的间隙,这是一些屏幕截
1、系统环境如下图: 2、为该系统添加一块新的虚拟硬盘,添加后需重启虚拟机,否则系统不识别;如下图,/dev/sdc 是新添加的硬盘; 3、fdisk /dev/sdc为新硬盘创建分区:
1、nagios简介 nagios是一款开源的电脑系统和网络监视工具,能有效监控windows、linux和unix的主机状态,交换机路由器等网络设置,打印机等。在系统或服务状态异常时发
越来越多人开始习惯用手机上网,浏览网页、查看邮件···移动化已经成为互联网发展必然趋势,包括facebook在内的很多互联网公司都将移动广告作为下一个淘金地
1.图片处理 1.圆角图片 复制代码 代码如下: /** * 转换成圆角 * &n
Microsoft SQL Server Management Studio是SQL SERVER的客户端工具,相信大家都知道。我不知道大伙使用导入数据的情况怎么样,反正我最近是遇到过。主要是因为没
debian6系统: 首先先安装mysql吧: 打开终端(root)用户登入 apt-get purge mysql-server-5.5 安装完成后: 默认情况下Mysql只允许本地登录
fedora16英文环境下支持中文输入法的方法 fedora16英文环境下支持FCITX的中文输入法: $ im-chooser 就会出现选择界面,选择第二个就行了。
Net预编译命令 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe -? 显示说明 我们需要选择的命令为&n
有的时候电脑出现一些故障有的时候通过将其修改bios设置的方法来解决故障,那么在bios上设置能不能将电脑恢复出厂设置呢?其实也是可以的。方法也很简单的,只要会进入电脑的bios懂的上面英文的意思就
笔者曾介绍过Deepin 将对龙芯进行全面支持,打造最优美龙芯电脑桌面。现在Deepin团队移植工作取得了突破性的成果,Deepin桌面已经在龙芯3A和龙芯3B电脑上成功运行起来了。 以下为龙芯3
在安装一些软件之后,我们的电脑总是会发生一点小变化,不是桌面上多了几个网址图标,就是IE浏览器的默认主页被篡改成乱七八糟的网址。最可气的是,在IE设置中将默认主页改回来后,下次启动Win7后又变了回
“注册表编辑器怎么打开”虽说不是很难的问题,但是对于对电脑常识不是很擅长的网民来说,当电脑出现问题或需要更改设置时,着实还是件头疼的问题。因为需要打开注册表进行操作解决。那么如何打开注册表编辑器呢?
这篇文章重点介绍10个重要的WordPress安全插件和技巧,用来保护WordPress网站或者博客。 1. WP Security 人工帮助你修复被黑客入侵的网站,只要按照他们网站上的联系电话
其实运用object和javascript调用外部文件,也能实现不同栏目调用不同友情链接,即相当于调用不同栏目友情链接文件, {dede:field.typeid/}来获取当前栏目的ID。
我有一个复值矩阵。 如果我发出命令: plot(myMatrix) 然后它在图形设备上显示一种散点图,X 轴标记为 Re(myMatrix),Y 轴标记为 Im(myMatrix)。这显示了我正在寻找
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 4年前关闭。 Improve this questi
我是一名优秀的程序员,十分优秀!