我和我的团队目前正在开发一个 Android 应用程序来进行快速实时和非实时图像处理。
我们面临两个问题:
首先,我们想将 Bitmap 转换为 Texture 以使用 OpenGL 着色器处理图片,然后将其转换回 Bitmap。我们尝试了一些不成功的实现,例如在 SurfaceTexture 和 Renderer 中使用 GLUtils.texImage2D 函数。
我们的第二个问题是我们目前不知道如何在我们的实时相机活动中保存纹理。我们使用 OnFrameAvailableListener 来处理图像。但就目前而言,我们无法保留原始纹理。
我们希望有人可以为我们的问题提供答案。提前致谢 !
我编写了一个示例应用程序,它允许 Android 用户拍照并将视图中的文本内容作为图像的叠加层并保存到图库相册中:
我想要的是在加入两个图像之前转换文本位图。具体来说,我想使文本曲线在两侧向上(模拟环绕圆柱体),并使其顶部比底部大(模拟自上而下的透视),如下所示:
无需解释相机图像即可确定曲率或透视变化量。问题是如何操作位图以便可以进行两个转换。
这是我用来将未转换的文本放入相机图像和图库的代码:
private void combinePictureWithText(String fileName) {
Log.v(TAG, "combinePictureWithText");
int targetW = getWindowManager().getDefaultDisplay().getWidth();
int targetH = getWindowManager().getDefaultDisplay().getHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 1;
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(photoW/targetW, photoH/targetH);
}
Log.v(TAG, "Scale Factor: " …Run Code Online (Sandbox Code Playgroud) 我需要从 imageView 中获取图像并将其作为位图。
String s = getIntent().getStringExtra("ImageUri");
mImageViewFilter = (ImageView) findViewById(R.id.imageViewFilter);
Glide.with(this)
.load(s)
.into(mImageViewFilter);
Bitmap bitmap = ((BitmapDrawable)mImageViewFilter.getDrawable()).getBitmap();
Run Code Online (Sandbox Code Playgroud)
您可以在 mImageViewFilter 中看到,我正在使用其 URI 和 Glide 库加载照片。我的下一步是拍摄 mImageViewFilter 中的这张照片并将其制作为位图。在最后一行代码之后有一个异常。我究竟做错了什么?
我是位图的新手,每像素使用 16 位Format16bppRgb555;
我想从位图数据中提取 RGB 值。这是我的代码
static void Main(string[] args)
{
BitmapRGBValues();
Console.ReadKey();
}
static unsafe void BitmapRGBValues()
{
Bitmap cur = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format16bppRgb555);
//Capture Screen
var screenBounds = Screen.PrimaryScreen.Bounds;
using (var gfxScreenshot = Graphics.FromImage(cur))
{
gfxScreenshot.CopyFromScreen(screenBounds.X, screenBounds.Y, 0, 0, screenBounds.Size, CopyPixelOperation.SourceCopy);
}
var curBitmapData = cur.LockBits(new Rectangle(0, 0, cur.Width, cur.Height),
ImageLockMode.ReadWrite, PixelFormat.Format16bppRgb555);
try
{
byte* scan0 = (byte*)curBitmapData.Scan0.ToPointer();
for (int y = 0; y < cur.Height; ++y)
{
ulong* curRow = (ulong*)(scan0 + curBitmapData.Stride * …Run Code Online (Sandbox Code Playgroud) 我的 onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_INTENT_REQUEST_CODE && resultCode == RESULT_OK && data != null && data.getExtras() != null) {
if (data.getData() == null) {
bitmap = (Bitmap) data.getExtras().get("data");
resultImage.setImageBitmap(bitmap);
} else {
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData());
resultImage.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
Toast.makeText(this, "Cancelled", Toast.LENGTH_SHORT).show();
}
}
Run Code Online (Sandbox Code Playgroud)
将“位图”转换为“Base64”
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = …Run Code Online (Sandbox Code Playgroud) 好的,所以我刚开始使用 WinAPI 来绘制位图图像。因此,如果我的代码绝对是垃圾,我深表歉意。无论如何,我该怎么做?本质上,我想使用这样HBITMAP的简单unsigned char像素缓冲区创建一个对象CreateBitmap()......
HBITMAP hbm = CreateBitmap(width, height, 1, 24, buffer);
Run Code Online (Sandbox Code Playgroud)
(显然这是每像素 3 字节)
在我尝试渲染它之前,这似乎工作正常。现在,我只想保持简单并在屏幕上绘制一个 100 x 100 的黑色像素方块,但什么也没显示。如果有人能指出我的残暴代码中的错误,我将不胜感激。
这是我的设置(我知道很多事情都可以改进,我现在只想尽可能地简约,实际上屏幕上会出现一些东西):
HBITMAP hbm = NULL;
void window_init(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static unsigned char buffer[30000] = {0};
hbm = CreateBitmap(100, 100, 1, 24, buffer);
}
void window_draw(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, hbm);
BitBlt(hdc, …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用以下代码将位图转换为 8bpp 灰度
private Bitmap ConvertPixelformat(ref Bitmap Bmp)
{
Bitmap myBitmap = new Bitmap(Bmp);
// Clone a portion of the Bitmap object.
Rectangle cloneRect = new Rectangle(0, 0, Bmp.Width, Bmp.Height);
PixelFormat format = PixelFormat.Format8bppIndexed;
Bitmap cloneBitmap = myBitmap.Clone(cloneRect, format);
var pal = cloneBitmap.Palette;
for (i = 0; i < cloneBitmap.Palette.Entries.Length; ++i)
{
var entry = cloneBitmap.Palette.Entries[i];
var gray = (int)(0.30 * entry.R + 0.59 * entry.G + 0.11 * entry.B);
pal.Entries[i] = Color.FromArgb(gray, gray, gray);
}
cloneBitmap.Palette = pal;
cloneBitmap.SetResolution(500.0F, …Run Code Online (Sandbox Code Playgroud) 我创建了一个位图字体,基本上是一个 256x256 的 png 图像,其中每个字符占据 8x8 平铺。我想将它与 Pillow 一起用作 ImageFont,但 Pillow 文档中没有关于此的信息。它说我可以像这样加载位图字体
font = ImageFont.load("arial.pil")
Run Code Online (Sandbox Code Playgroud)
但是“PIL 使用自己的字体文件格式来存储位图字体。” 所以我猜 png 文件不起作用。我如何告诉 PIL 使用所述位图以及每个字符的位置?
我想将 CameraX 预览从 previewView 转换为位图。类似于 textureView.bitmap 的东西
我已经用纹理视图尝试过它并且效果很好,我可以截取相机视图的屏幕截图,但相机被拉伸了。
screenshot bitmap android-bitmap takesscreenshot android-camerax
在 Delphi 10.4 中,我PNG在 DESIGN-TIMEPicture的TImage. 下面是它在运行时的样子:
这是TImage组件的副本(可以在设计时将其粘贴到任何 Delphi VCL 应用程序项目中):
object Image1: TImage
Left = 46
Top = 200
Width = 32
Height = 32
AutoSize = True
Center = True
Picture.Data = {
0954506E67496D61676589504E470D0A1A0A0000000D49484452000000200000
00200806000000737A7AF40000000473424954080808087C086488000006F749
44415478DAB557694C545714BE33C3BE8A0CEBB096224EA94241B16AACA68520
6DA1D1D485B00A1421DA0A36A9B64D9AFE68AA69A340451B4A41405903D6A5D4
0AB4285B59442236884C054640C080EC8475A6DF19670803B40C466F72F3DEBB
E7DC73BE77EED92EE78083195BB74A87310E872D1E52261E9D6409CD8FD9CB1A
9CD3EEF66C9B99E11800682FD62F9DBA3F34AE155CD9F212016C788500CCD2FB
12069002002FB8F2C1336658C9CCCC8C595B5B333E9FCF74747494D827262658
5F5F1FEBECEC64DDDDDD4C2291BC180011756DCCDDDD9DB9B8B8700C0D0DB781
F23EE69B988E98AB3149D300A608F32FCCC2D1D1D18AC6C646697D7D3D1B1F1F
7F7E001D1C4DDE9FF61BB8BABABA2158390E2B38AA625AA9544AE77672727232
A3ACAC4C72E7CE9DE703D06624E0D55B39D740F146B960311E7C7CEBE2FD1814
24C0D4126D6DED20ACA5606D06F4C778B791F3D7E211D4D2D2222A2C2C645353
532B03D0C2B7E5DDB35C2B81A04758F91CCF6A0827538FE15D909E9E3E3A3838
C8A2A3A3D53435351F81660E3C6E780AC1F32D9EB6E01BC6DC03BF28CECDCD55
02B12C0091B135EFAEA5300B020EE25C47F4F5F58F40681CBE33E16C41999999
32566F6F6FE6EAEA7A06B443A07D353636F60D9C541FDF4998FBB13685E9FBF0
E1C3E24B972E91655403D0A9BB9A57C45FC36EDDBAC56C6C6CC811AF41E07B10
10505C5C9CAD385B3B3B3BB66FDF3E3FD02E83562A168BDFA9ADAD65BEBEBE4C
4B4BEB14D663C91260DD585A5A2A229ACA51A008C3D0D0500AC32710C687996D
9293933B07060664341E8FC76263634DF0ECC1E7087CC3283E3E5E6A6E6E4EC0
084496DC12B538822D29292992E1E1E19501387AF4A8B58686861842FA6062D3
C4C44425F6C0C040261008C450640D808EA03FA410B4B5B5657BF7EED5E772B9
F7C839B13F0CE199565252B23C00B1BA1E2F47DD8C6133B3B7B77F1B024A20A0
1C7FB89D12CEFC41494A4F4FAF083C9EE0F1E9E8E8B8A170382B2B2B0627F507
2D934214FB8500285D16C03FE48482D7964F692B1CB0D0F6828282721500D800
80F085038015BEABA9A939BE2C80475AAB78D70C6CC98918D2F0699830069B63
E17C090B938A9A9A1A333636FE043CF1E0F901611B035F99A3D3319A98987882
5E047A596B6BEB0E959D70FDFAF5CCC7C7E7276C8EC0E688FCFCFC54C4B412BB
A9A929454A1814FD0C9E94F2F2F28FAAAAAAE6E854CC6262622CE00B5DA077F7
F4F408540680F8673B77EE3C0F2121D81C92969676A1B7B757891DF5821D3E7C
9852723A78322A2A2A422B2B2B957800500DA1494969020074560A200DC283B1
3918002EFE078040F06480E70200842C04101212C2B3B0B098067D1200B4570A
2019C2C3B1393C2F2FEF7C5B5B9B123BF508E1E1E107E445291500221602A023
803FD111407F8FE5F2D550439F97CB336106060674C671107E849C1085256161
9D4792A266E563F02490133E7DFA344691296950B644CA563861797B7BFB7625
00280F7F4F334EA81A93A671197B5D660154C326544395E34BC50100DFDFBE7D
FBD81C002C34F4E819BF7BD7C2698F437F4781C340E7AF5C297BA3896FC7BB6F …Run Code Online (Sandbox Code Playgroud)