6

İki görüntü arasında geçiş animasyonunu uygulayarak görüntü listesinden animasyonlu video yapmak istiyorum. Ben, böyle SO üzerinde birçok benzer sorular bulundu Android, hareketli görüntüyü listeden oluştur

Android Screen capturing or make video from images

Android- How to make video using set of images from sd card?

benzer Tüm SO sorular bunun için animasyon kullanılan önermek, ama biz nasıl saklayabilir

video dosyası animasyonlu görüntüler o? Bu video görüntüsünü video oluşturmak için herhangi bir Android kütüphanesi var mı?

Herhangi bir Yardım için teşekkür ederiz ... !!! Teşekkürler Peşin

+1

Sorunuz için bir yol buluyor musunuz? –

cevap

1

JCodec (http://jcodec.org) adı verilen saf bir java çözümü kullanabilirsiniz. İşte JCodec düşük seviye API kullanarak yapar bir CORRECTED basit sınıf var:

public class SequenceEncoder { 
    private SeekableByteChannel ch; 
    private Picture toEncode; 
    private RgbToYuv420 transform; 
    private H264Encoder encoder; 
    private ArrayList<ByteBuffer> spsList; 
    private ArrayList<ByteBuffer> ppsList; 
    private CompressedTrack outTrack; 
    private ByteBuffer _out; 
    private int frameNo; 
    private MP4Muxer muxer; 

    public SequenceEncoder(File out) throws IOException { 
     this.ch = NIOUtils.writableFileChannel(out); 

     // Transform to convert between RGB and YUV 
     transform = new RgbToYuv420(0, 0); 

     // Muxer that will store the encoded frames 
     muxer = new MP4Muxer(ch, Brand.MP4); 

     // Add video track to muxer 
     outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, 25); 

     // Allocate a buffer big enough to hold output frames 
     _out = ByteBuffer.allocate(1920 * 1080 * 6); 

     // Create an instance of encoder 
     encoder = new H264Encoder(); 

     // Encoder extra data (SPS, PPS) to be stored in a special place of 
     // MP4 
     spsList = new ArrayList<ByteBuffer>(); 
     ppsList = new ArrayList<ByteBuffer>(); 

    } 

    public void encodeImage(BufferedImage bi) throws IOException { 
     if (toEncode == null) { 
      toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420); 
     } 

     // Perform conversion 
     for (int i = 0; i < 3; i++) 
      Arrays.fill(toEncode.getData()[i], 0); 
     transform.transform(AWTUtil.fromBufferedImage(bi), toEncode); 

     // Encode image into H.264 frame, the result is stored in '_out' buffer 
     _out.clear(); 
     ByteBuffer result = encoder.encodeFrame(_out, toEncode); 

     // Based on the frame above form correct MP4 packet 
     spsList.clear(); 
     ppsList.clear(); 
     H264Utils.encodeMOVPacket(result, spsList, ppsList); 

     // Add packet to video track 
     outTrack.addFrame(new MP4Packet(result, frameNo, 25, 1, frameNo, true, null, frameNo, 0)); 

     frameNo++; 
    } 

    public void finish() throws IOException { 
     // Push saved SPS/PPS to a special storage in MP4 
     outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList)); 

     // Write MP4 header and finalize recording 
     muxer.writeHeader(); 
     NIOUtils.closeQuietly(ch); 
    } 

    public static void main(String[] args) throws IOException { 
     SequenceEncoder encoder = new SequenceEncoder(new File("video.mp4")); 
     for (int i = 1; i < 100; i++) { 
      BufferedImage bi = ImageIO.read(new File(String.format("folder/img%08d.png", i))); 
      encoder.encodeImage(bi); 
     } 
     encoder.finish(); 
    } 
} 
+9

BufferedImage ve ImageIO, Android'te desteklenmiyor –

6

Android AWT en BufferedBitmap ne de AWTUtil için desteklemez, bu Java SE içindir. Şu anda SequenceEncoder ile çözüm jcodec'in Android sürümüne entegre edilmiştir. Bunu org.jcodec.api.SequenceEncoder paketinden kullanabilirsiniz. durumda

try { 
    File file = this.GetSDPathToFile("", "output.mp4"); 
    SequenceEncoder encoder = new SequenceEncoder(file); 

    // only 5 frames in total 
    for (int i = 1; i <= 5; i++) { 
     // getting bitmap from drawable path 
     int bitmapResId = this.getResources().getIdentifier("image" + i, "drawable", this.getPackageName()); 
     Bitmap bitmap = this.getBitmapFromResources(this.getResources(), bitmapResId); 
     encoder.encodeNativeFrame(this.fromBitmap(bitmap)); 
    } 
    encoder.finish(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

// get full SD path 
File GetSDPathToFile(String filePatho, String fileName) { 
    File extBaseDir = Environment.getExternalStorageDirectory(); 
    if (filePatho == null || filePatho.length() == 0 || filePatho.charAt(0) != '/') 
     filePatho = "/" + filePatho; 
    makeDirectory(filePatho); 
    File file = new File(extBaseDir.getAbsoluteFile() + filePatho); 
    return new File(file.getAbsolutePath() + "/" + fileName);// file; 
} 

// convert from Bitmap to Picture (jcodec native structure) 
public Picture fromBitmap(Bitmap src) { 
    Picture dst = Picture.create((int)src.getWidth(), (int)src.getHeight(), ColorSpace.RGB); 
    fromBitmap(src, dst); 
    return dst; 
} 

public void fromBitmap(Bitmap src, Picture dst) { 
    int[] dstData = dst.getPlaneData(0); 
    int[] packed = new int[src.getWidth() * src.getHeight()]; 

    src.getPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight()); 

    for (int i = 0, srcOff = 0, dstOff = 0; i < src.getHeight(); i++) { 
     for (int j = 0; j < src.getWidth(); j++, srcOff++, dstOff += 3) { 
      int rgb = packed[srcOff]; 
      dstData[dstOff]  = (rgb >> 16) & 0xff; 
      dstData[dstOff + 1] = (rgb >> 8) & 0xff; 
      dstData[dstOff + 2] = rgb & 0xff; 
     } 
    } 
} 

Eğer fps değiştirmek gerekiyorsa, SequenceEncoder özelleştirebilirsiniz: Burada

jcodec kullanarak Bit haritası serisinden MP4 dosyasını oluşturmak için bir çözümdür.

+1

Video süresini ne etkiler ve bu durumda nasıl tanımlayabiliriz? Kodum 1 kare video oluşturdu (bence). –

+1

Ve bir (sanırım) 1-ms video. –

+0

SequenceEncoder için belirgin bir özelleştirme yok. – mradzinski

İlgili konular