Как мне сохранить UIImage как BMP? - PullRequest
1 голос
/ 29 августа 2009

Можно ли сохранить (записать в файл) UIImage объект в виде растрового файла (расширение .bmp) в каталоге документов iPhone?

Заранее спасибо.

Ответы [ 4 ]

3 голосов
/ 29 августа 2009

Я не думаю, что BMP поддерживается на iPhone. Может быть, кто-то написал категорию для UIImage, которая делает сохранение в BMP, но я не знаю ни о какой. Полагаю, вам нужно будет получить растровые данные из UIImage и написать их самостоятельно, BMP - довольно простой формат файла. Все, что вам нужно сделать, это выписать заголовок и затем несжатые данные. Заголовок представляет собой структуру с именем BITMAPINFOHEADER, см. MSDN . Получение растровых данных UIImage описано в техническом вопросе Apple & A1509 .

.
2 голосов
/ 29 августа 2009

Сейчас я не беспокоюсь о размере. Просто хочу знать, могу ли я записать данные изображения в виде файла .bmp.

1 голос
/ 17 июля 2012

Понимаю, что это старый пост, но в случае, если кто-то найдет его, как я искал решение. В основном мне нужно было FTP UIImage в виде небольшого BMP, поэтому я взломал этот грубый класс в MonoTouch. Я позаимствовал у zxing.Bitmap.cs и Пример 1 из статьи BMP из Википедии . Похоже на работу. Возможно, было бы проще сделать расширение вроде AsBMP () или что-то в этом роде. (Я не знаю, каков эквивалент цели-c, но, надеюсь, это кому-нибудь пригодится.)

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.CoreGraphics;
public class BitmapFileRGBA8888
{
    public byte[] Data; // data needs to be BGRA
    public const int PixelDataOffset = 54;

    public BitmapFileRGBA8888(UIImage image)
    {
        CGImage imageRef = image.CGImage;
        int width = imageRef.Width;
        int height = imageRef.Height;
        Initialize((uint)width, (uint)height);
        CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB();

        IntPtr rawData = Marshal.AllocHGlobal(height*width*4);
        CGContext context = new CGBitmapContext(
            rawData, width, height, 8, 4*width, colorSpace, CGImageAlphaInfo.PremultipliedLast
        );
        context.DrawImage(new RectangleF(0.0f,0.0f,(float)width,(float)height),imageRef); // RGBA

        byte[] pixelData = new byte[height*width*4];
        Marshal.Copy(rawData,pixelData,0,pixelData.Length);
        Marshal.FreeHGlobal(rawData);

        int di = PixelDataOffset;
        int si;
        for (int y = 0; y < height; y++)
        {
            si = (height-y-1) * 4 * width;
            for (int x = 0; x < width; x++)
            {
                CopyFlipPixel(pixelData, si, Data, di);
                di += 4; // destination marchs forward
                si += 4;
            }
        }
    }

    private void CopyFlipPixel(byte[] Src, int Src_offset, byte[] Dst, int Dst_offset)
    {
        int S = Src_offset;
        int D = Dst_offset + 2;
        Dst[D--] = Src[S++]; // R
        Dst[D--] = Src[S++]; // G
        Dst[D--] = Src[S++]; // B
        Dst[Dst_offset+3] = Src[S]; // alpha
    }

    private void Initialize(uint W, uint H)
    {
        uint RawPixelDataSize = W * H * 4;
        uint Size = RawPixelDataSize + 14 + 40;
        Data = new byte[Size];
        Data[0] = 0x42; Data[1] = 0x4D; // BITMAPFILEHEADER "BM"
        SetLong(0x2, Size); // file size
        SetLong(0xA, PixelDataOffset); // offset to pixel data
        SetLong(0xE, 40); // bytes in DIB header (BITMAPINFOHEADER)
        SetLong(0x12, W);
        SetLong(0x16, H);
        SetShort(0x1A, 1); // 1 plane
        SetShort(0x1C, 32); // 32 bits
        SetLong(0x22, RawPixelDataSize);
        SetLong(0x26, 2835); // h/v pixels per meter device resolution
        SetLong(0x2A, 2835);
    }

    private void SetShort(int Offset, UInt16 V)
    {
        var byts = BitConverter.GetBytes(V);
        if (!BitConverter.IsLittleEndian) Array.Reverse(byts);
        Array.Copy(byts,0,Data,Offset,byts.Length);
    }
    private void SetLong(int Offset, UInt32 V)
    {
        var byts = BitConverter.GetBytes(V);
        if (!BitConverter.IsLittleEndian) Array.Reverse(byts);
        Array.Copy(byts,0,Data,Offset,byts.Length);
    }
} // END CLASS

В основном

var Bmp = new BitmapFileRGBA8888(TempImage);
FTP.UploadBin(Bmp.Data, "test.bmp");        // or just write as binary file
0 голосов
/ 29 августа 2009

Поскольку BMP не является сжатым форматом, это хорошая идея?

Предположительно, размер изображения еще важнее на портативных устройствах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...